数据存储-持久化技术
2016-03-20 22:06
246 查看
使用文件存储数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public void save(String inputText){ FileOutputStream out = null; BufferedWriter writer = null; try { out = openFileOutput("data",Context.MODE_PRIVATE); writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write(inputText); } catch (IOException e) { e.printStackTrace(); } finally { try { if(writer != null){ writer.close(); } } catch (IOException e){ e.printStackTrace(); } } } |
读取文件就将
FileOutputStream->FileInputStream,
BufferedWriter->BufferedReader,
wirter.write->reader.redline()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2122 | public String load(){ FileInputStream inputStream = null; BufferedReader reader = null; StringBuilder content = new StringBuilder(); try { inputStream = openFileInput("data"); reader = new BufferedReader(new InputStreamReader(inputStream)); String line = ""; while ((line = reader.readLine()) != null){ content.append(line); } } catch (IOException e){ e.printStackTrace(); } finally { if (reader != null){ try { reader.close(); } catch (IOException e){ e.printStackTrace(); } } } return content.toString(); } |
使用SharedPreferences存储数据
存放数据1 2 3 4 5 | SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit(); editor.putString("name","Gaby"); editor.putBoolean("married",false); editor.putInt("age",19); editor.commit(); |
取数据
1 2 3 4 56 | SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);//输入相对应的文件名 String name = pref.getString("name", ""); int age = pref.getInt("age",29); Boolean married = pref.getBoolean("married",false); Log.d("MainActivity","name is" + name); Log.d("MainActivity","age is" + age); Log.d("MainActivity","married is " + married); |
1 2 3 4 56 | SharedPreferences pref; SharedPreferences.Editor editor; pref = PreferenceManager.getDefaultSharedPreferences(this); editor = pref.edit(); editor.putBoolean("remember_password", true); editor.putString("account", account); editor.putString("password", password); editor.commit(); editor.clear();//将SharedPreference中的数据全部清除掉t |
使用SQLite(DBMS)创建数据库存储数据
细节理解:
1 2 3 | dbHelper = new MyDatabaseHelpoer(MainActivity.this,"BookStore.db",null,1);//构建一个MydatabaseHelper对象 dbHelper.getWritableDatabase();//没找到BookStore.db这个数据库,即调用onCreate()创建该数据库 |
一个MyDatabaseHelper的对象创建一个数据库,在onCreate()函数中执行对这个数据库的操作
创建好后,用ddms的explorer(顶上
Tools->Android->Android Device Monitor->File Exploer,FileExplorer里的文件目录即为模拟器的文件目录)不能看到改数据库创建的表,用adb shell(adb是一个对连接的usb设备或者模拟器的调试器)看。要使用adb,需要先配置环境变量:增加
C:\Users\Gaby\AppData\Local\Android\sdk\platform-tools到系统变量里面的Path,就可以在android studio 的terminal里使用
FileExplorer中
/data/data/com.example.gaby.databasetest/databases/目录下有两个文件
xxx.db数据库
xxx.db-journal是为让数据库能够支持事务而产生的临时日志文件
建表语句:
1 2 3 4 56 | public static final String CREATE_BOOK = "create table Book (" + "name text, " + "author text, " + "price real, " + "pages integer, " + "id integer primary key autoincrement)"; |
adb命令列举:
adb devices列出当前设备
adb shell进入设备的控制台
cd /data/data/com.example.gaby.databasetest/databases/进入模拟器该文件夹下
ls列出该目录下文件夹
sqlite3 BookStore.db打开数据库
SQLite命令:
.table显示数据库中有哪些表
.schema查看建表语句
.exit/
.quit退出改数据库
select * from tableName;(有分号) 查询该表下有哪些纪录
接着
exit退出设备控制台(adb)
注意
execSQL(String s)传入的是字符串
CRUD
以下是按Android提供过的API来做的,实际上还可直接用SQL来操作数据库,见《第一行代码》page 260向数据库中添加数据(db.insert()) (·)Create 添加
1 2 3 4 56 | addData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); //di yi zu values.put("name", "Game Of Thrones"); values.put("price",70.29); values.put("author","George Martin"); values.put("pages",800); db.insert("Book", null, values); //di er zu values.clear(); values.put("name","KaiFu's Saying"); values.put("price",50.34); values.put("author","KaiFu"); values.put("pages",300); db.insert("Book", null, values); } }); |
查询数据(db.query()) (·)Retrieve
1 2 3 4 56 | queryData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor cursor = db.query("Book",null,null,null,null,null,null); if(cursor.moveToFirst()){ do{ String name = cursor.getString(cursor.getColumnIndex("name")); String author = cursor.getString(cursor.getColumnIndex("author")); int pages = cursor.getInt(cursor.getColumnIndex("pages")); double price = cursor.getDouble(cursor.getColumnIndex("price")); Log.d("MainActivity","book name is" + name); Log.d("MainActivity","book author is" + author); Log.d("MainActivity","book pages is " + pages); Log.d("MainActivity","book price is " + price); }while(cursor.moveToNext()); } } }); |
db.query()返回Cursor对象
更新数据(db.update()) (·)Update 更新
注意:在MyDatabaseHelper中的onUpgrade()方法是用于升级数据库(如 多建/删除 一张表)。而更新数据,则是在特定表上修改数据
1 2 3 4 56 | updataData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("price",12.33); db.update("Book", values, "name = ?",new String [] {"Game Of Thrones"}); } }); |
1 2 3 4 56 | deleteData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete("Book","pages > ?", new String[] { "300" }); } }); |
数据库的事务(ACID要么全成功,要么全失败)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2122 | replaceData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.beginTransaction(); try { db.delete("Book",null,null); ContentValues values = new ContentValues(); values.put("name","MySQL Crash Course"); values.put("price",12.93); values.put("pages",400); values.put("author","Ben Forta"); db.insert("Book",null,values); db.setTransactionSuccessful(); } catch (Exception e){ e.printStackTrace(); } finally { db.endTransaction(); } } }); |
db.setTransactionSuccessful()得不到执行,当结束事务
db.endTransaction()时发现事务未成功执行,旧数据就不会被删除
升级数据库的最佳写法
需要注意以下几点:当用户下载的新版本覆盖安装旧版本时,实际上安装好的新版本应用程序具备所有新功能,只是数据库还残留在上一个版本,此时如果代码如下:
1 2 3 4 56 | private MyDatabaseHelpoer dbHelper; dbHelper = new MyDatabaseHelpoer(MainActivity.this,"BookStore.db",null,6); Button createDatabase = (Button) findViewById(R.id.createDatebase); createDatabase.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dbHelper.getWritableDatabase(); } }); |
1 2 3 | private MyDatabaseHelpoer dbHelper; dbHelper = new MyDatabaseHelpoer(MainActivity.this,"BookStore.db",null,6); dbHelper.getWritableDatabase(); |
dbHelper.getWritableDatabase()是在没有名为”BookStore.db”的数据库时就创建(执行
MydatabaseHelper的
onCreate()函数)。如果本来就有,就会去执行
onUpdate()函数,判断旧版本是哪一个,进而做出对数据库的更改
新版本的不光要在onUpgrade()做出更改,还应以备旧版本更新。更要在onCreate()中做出完整的创建工作,以备用户直接下载新版本
在
onUpgrade()中的
case不加
break, 原因就是如果跨版本升级。比如旧版本的数据库停留在第二版,应用安装好了,且新版本的数据库是第8版,在更新数据库时就要从第二版更新到第八版,依次升级,升级结束后此时的数据库版本号为8
1 2 3 4 56 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { switch (oldVersion){ case 4: db.execSQL(CREATE_MILK); case 5: db.execSQL("alter table Milk add column volume real"); } } |
个人想法
对于版本更新的问题,比如手机版的qq,不可能没更新一个版本就在,onUpgrade()里加一个型号,应该会要有个版本间隔(允许的最新和最旧的版本区间),不然200年以后,以腾讯的产品迭代速度,onUpgrade()里面的代码就太多了…相关文章推荐
- Codeforces Round #343 (Div. 2) A B C D
- Android——简易音乐播放器
- 第四周项目四(3)
- TF-IDF与余弦相似性的应用(一):自动提取关键词
- Markdown语法,快速入门
- 写个好简历
- C 标准库——<string.h>
- 学习笔记-第四周-交流电机选优
- json.loads(s) returns error message like this: ValueError: Invalid control character at: line 1 column 33 (char 33)
- HDU 1159 Common Subsequence
- 猎豹MFC--钩子技术HOOK
- SQL SERVER-常用命令2
- 别人写的UNICODE的文本,汉字字符都可以用记事本查看,注意记事本识别编码的方式为BOM
- C#程序设计教程编程题(二)
- CentOS系统程序包管理之---rpm、yum和编译
- 2016蓝桥杯江西省赛
- 博客第一天
- iOS开发网络篇—NSURLConnection基本使用
- 2016年蓝桥杯比赛心得
- 在Linux运行期间升级Linux系统(Uboot+kernel+Rootfs)