持久化技术简介
- 数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失
- Android 系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储、SharedPreference 存储以及数据库存储
文件存储
将数据存储到文件中
Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中
- 第一个参数是文件名,不包含路径,因为所有的文件都是默认存储到/data/data/packagename/files/ 目 录 下 的
- 第二个参数是文件的操作模式,主 要 有 两 种 模 式 可 选 ,
MODE_PRIVATE 和 MODE_APPEND。其中 MODE_PRIVATE 是默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容,而 MODE_APPEND 则表示如果该文件已存在就往文件里面追加内容,不存在就创建新文件 openFileOutput返回一个FileOutputStream对象
FileOutputStream out = openFileOutput("data",Context.MODE_PRIVATE); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write(data);
从文件中读取数据
Context中提供了一个openFileInput()方法,用于从文件中读取数据
- 只有一个参数,即读取的文件名
返回一个FileInputStream对象
FileInputStream in = openFile("data"); BufferedReader reader = new BufferedReader(new InputStreamReader(in));
SharedPreferences存储
- sharedPreferences是使用键值对的方式来存储数据的
将数据存储到 SharedPreferences 中
- Android主要提供了三种方式来获取SharedPreferences对象
- Context类中的getSharedPreferences()方法
- 第一个参数用于指定Sharedpreferences的文件名,如果指定的文件不在则创建一个,SharedPreferences 文件都是存在/data/data/packagename/shared_prefs/目录下的
- 第二个参数用于指定操作模式主要有两种模式可以选
择,MODE_PRIVATE 和 MODE_MULTI_PROCESS。MODE_PRIVATE 仍然是默认的操作模式,和直接传入 0 效果是相同的,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写。 MODE_MULTI_PROCESS 则一般是用于会有多个进程中对同一个 SharedPreferences 文件进行读写的情况
- Activity类中getPreferences()方法
- 只接收一个操作模式的参数,因为使用这个方法会自动将当前类名作为文件名
- PreferencesManager中的getDefaultSharedPreferences()方法
- 这是一个静态方法,接收一个Context参数,自动将当前程序的包名作为前缀来命名
- Context类中的getSharedPreferences()方法
向SharedPreferences存储数据主要有一下几步:
- 调用SharedPreferences的edit()方法来获取一个SharedPreferences.editor对象
- 向SharedPreferences.editor对象中添加数据
调用commit()方法将添加的数据提交,从而完成数据存储的操作
SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit(); editor.putString("name","Tom"); editor.putInt("age",28); editor.putBoolean("married",false); editor.commit();
从SharedPreferences中读取数据
SharedPreferences对象中提供了一系列的get()方法用于对数据进行读取,每种get方法都对应SharedPreferences.Editor对象中的一种put方法
SharedPreferences pref = getSharedPerences("data",MODE_PRIVATE); int age = pref.getInt("age",0); boolean married = pref.getBoolean("married",false);
SQLite数据存储
创建数据库
- Android提供了一个SQLiteOpenHelper帮助类,借助这个类就可以对数据库进行创建和升级
- SQLiteOpenHelper是一个抽象类,它有两个抽象方法,分别为onCreate(),onUpgrade()。这两个方法分别用于创建和升级数据库
- SQLiteOpenHelper中还有两个非常重要的实例方法,getReadableDatabase()和getWritableDatabase()方法。这两个方可以用于创建或打开一个现有的数据库(如果数据库存在则打开,否则创建一个新的数据库)
- SQLiteOpenHelper中有两个构造方法可供重写,一般使用参数少的那个构造方法即可
- 第一个参数是Context
- 第二个参数是数据库名,即创建数据库时使用的名字
- 第三个参数允许我们在查询数据的时候返回一个Cursor对象
- 第四个参数表示当前数据库的版本号,可用于对数据库进行升级
数据库文件会存放在/data/data/packagename/databases目录下
public class MyDatabaseHelper extends SQLiteOpenHelper{ public static final String CREATE_BOOK = "create table book ("+"id integer primary key autocrement,"+"author text,"+"price real,"+"pages integer,"+"name text)"; private Context mContext; public MyDatabaseHelper(Context context,String name,CursorFactory factory,int version){ super(context,name,factory,version); mContext = context; } @Override public void onCreate(SQLiteDatabase db){ db.execSQL(CREATE_BOOK); } @Overrie public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){ }
升级数据库
- onUpgrade()方法用于进行数据库的升级
- 可通过版本号来进行数据库的升级
添加数据
SQLiteDatabase中提供了一个insert()方法,用于添加数据
- 第一个参数是表名
- 第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值 NULL
第三个参数是一个ContentValues对象,它提供了一系列的put()方法的重载,用于向ContentValues中添加数据
values.put("name", "The Da Vinci Code"); values.put("author", "Dan Brown"); values.put("pages", 454); values.put("price", 16.96); db.insert("Book", null, values);
更新数据
SQLiteDatabase提供了一个update()方法,用于更新数据
- 第一个参数为表名
- 第二个参数为ContentValues对象
第三、第四个参数用于去约束更新某一行或某几行中的数据,不指定的话默认就是更新所有行
values.put(“price”,10.99);
db.update(“Book”,values,”name = ?”,new String[]{“The Da Vinci Code”});
删除数据
SQLiteDatabase 中提供了一个 delete()方法专门用于删除数据
- 第一个参数是表名
第二、第三个参数又是用于去约束删除某一行或某几行的数据,不指定的话默认就是删除所有行
SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete("Book", "pages > ?", new String[] { "500" });
查询数据
SQLiteDatabase 中还提供了一个 query()方法用于对数据进行查询
- 第一个参数为表名
- 第二个参数用于指定去查询哪几列,如果不指定则默认查询所有列
- 第三、第四个参数用于去约束查询某一行或某几行的数据,不指定则默认是查询所有行的数据
- 第五个参数用于指定需要去 group by 的列,不指定则表示不对查询结果进行 group by 操作
- 第六个参数用于对 group by 之后的数据进行进一步的过滤,不指定则表示不进行过滤
第七个参数用于指定查询结果的排序方式,不指定则表示使用默认的排序方式
SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor cursor = db.query("Book", null, null, null, null, null, null);
使用SQL操作数据库
添加数据
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" }); db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "The Lost Symbol", "Dan Brown", "510", "19.95" });
- 更新数据
db.execSQL(“update Book set price= ?where name = ?”,new String[]{“10.99”,”The Da Vinci Code”}); - 删除数据
db.execSQL(“delete from Book where pages>?”,new String[]{“500”})
*查询数据
db.execSQL(“select * from Book”,null);
SQLite数据库的最佳实践
使用事务
- 事务的特性保证谋一系列的操作要么全部完成,要么一个都不完成
- Android中事务的标准用法
- 首先调用SQLiteDatabase的beginTransaction()方法来开启一个事务
- 然后在一个异常捕获的代码块中去执行具体的数据库操作
- 当所有的操作都完成之后,调用setTransactionSuccessful()表示事务已经执行成功
- 最后在finally代码块中调用endTransaction()来结束事务