l# 1 持久化技术简介
数据持久化指将呢些内存中瞬时数据保存到存储设备中,保证及时在设备关机的情况下,数据不会丢失。
Android系统提供三种方式用于简单的实现数据持久化功能,即文件存储、SharePreference存储和数据库存储。当然还有第四种,数据保存子啊手机的sd卡中。

2 文件存储

文件存储是Android最基本的一种数据存储方式,它不对存储内容做任何格式化处理,所有的数据都是原封不动地保存到文件中的。
适合存储一些简单的文本数据和二进制数据。如果使用文件存储的方式来保存一些较为复杂的文本数据,及需要定义一套自己的格式规范。

2.1 将数据存储到文件中

Context类提供了openFileOutput()方法:用于将数据存储到指定的文件中。
该方法接收两个参数:
第一个是文件名,不可以包含路径,因为所有文件都是默认存储在/data/data//files/目录下的。
第二个是文件的操作模式,主要由两种模式可以选择:

  • MODE_PRIVATE:默认的操作模式,表示当指定同样的文件名时,所写入的内容会覆盖原文件中的内容。
  • MODE_APPEND:表示如果该文件存在,就往文件中追加内容,如果不存在就添加新文件。

2.2 从文件中读取数据

Context类提供了一个openFileInput()方法,用于从文件中读取数据。
只接受一个参数,即要读取的文件名,然后自动到/data/data//files/目录下加载文件,并返回一个FileInputStream对象。

1.通过openFileInput()方法获取一个FileInputStream对象;
in = openFileInput(“data”);
2.借助它构建一个InputStreamReader对象,接着在使用InputStreamReader构建一个BufferedReader对象;
reader = new BufferedReader(new InputStreamReader(in));
3.通过BufferedReader进行一行行读取;
line = reader.readLine()
4.把文本全部读取出来,并存放在一个StringBuilder对象中。
StringBuilder content = new StringBuilder();
content.append(line);

3 SharePreferences存储

SharePerferences 使用键值对的方式来存储数据。

3.1 将数据存储到SharePreferences

先获取SharePreferences 对象。三种方式
1.Context 类中的getSharePreferences()方法
接收两个参数,第一个参数用于指定SharedPreferences文件的名称,不存在则创建一个,文件存放位置/data/data//shared_prefs/目录下。第二个参数用于指定操作模式,只由一种且为默认值MODE_PRIVATE,和直接传入0效果一样,表示只有当前的应用程序才可以对这个SharePreference文件进行读写。
2.Activity类中的getPreferences()方法
只接受一个操作模式参数,自动将当前活动的类名作为SharedPreferences的文件名。
3.PreferenceManager类中的getDefaultSharedpreferences()方法
静态方法,接收一个Context参数,并自动用当前应用程序的包名作为前缀来命名SharedPreference文件。
然后存储数据,三步:
1.调用SharedPreferences对象的edit()方法来获取一个SharedPreference.Editor对象。
2.向SharedPreferences.Editor对象添加数据。例如:putBoolean().putString()
3.调用apply()方法将添加的数据提交,从而完成数据存储。

3.2 从SharedPreference中读取数据

SharedPreferences对象中提供了一系列的get方法,接收两个参数,一个是键,一个是默认值,即表示当传入的键找不到对应的值会以什么样的默认值进行返回。

4 SQLite数据库存储

SQLite是一款轻量级的关系数据库,Android内置。

4.1 创建数据库

提供一个SQLiteOpenHelper帮助抽象类。

两个抽象方法:onCreate()和onUpgrade()

两个实例方法:getReadableDatabase()和getWritableDatabase() 如果数据库已存在则直接打开,否则创建一个新的数据库,并返回一个可对数据库进行读写操作的对象。
区别:当数据库不可写入时(如磁盘空间已满),getReadableDatabase()返回对象将以只读方式打开数据库,而getWritableDatabase()则将出现异常。

SQliteOpenHelper构造方法
第一个参数Context,有他才能对数据库进行操作。
第二个参数数据库名,创建数据库时使用的名称。
第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般是传入null。
第四个参数表示数据库版本号,可用对数据库进行升级操作。

构建后调用其方法getReadableDatabase() 或getWritableDatabas()方法创建数据库。

4.2 升级数据库

在onCreate方法添加新的表添加。由于数据库早已生成表,所有不会执行onCreate方法。
在onUpgrade()方法执行如果发现数据库以后目标表,则删除该表。然后执行onCreate()。
在SQLiteOpenHelper的构造方式里面修改第四个参数数据库版本,就可以让onUpgrade()方法执行。

以下使用辅助性的方法CRUD

4.3 添加数据

SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "The Data Code");
values.put("author", "Allen");
values.put("pages", 455);
values.put("price", 66.66);
db.insert("Book", null, values);

4.4 更新数据

SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values, "name = ?",
new String[] {"The Data Code"});

4.5 删除数据

SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages > ?", new String[] {"500"});

4.6 查询数据

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(TAG, "book name is " + name);
	    Log.d(TAG, "book author is " + author);
  	 	Log.d(TAG, "book pages is " + pages);
 	    Log.d(TAG, "book price is " + price);
  	 } while (cursor.moveToNext());
}
cursor.close();

4.7 使用SQL操作数据库

添加数据

db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",
			new String[] { "The Data Code", "Allen", "454", "16.96" });

更新数据

db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99",
			"The Data Code" });

删除数据

db.execSQL("delete from Book where pages > ?", new String[] { “500” });

查询数据

db.rawQuery("select * from Book", null);

5 使用LitePal 操作数据库

5.1 LitePal简介

LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式。
可以看详细使用文档,地址:http://github.com/LitePalFramework/LitePal

5.2 配置LitePal

1.编辑app/build.gradle文件
dependencies {
implements ‘org.litepal.android:core:1.3.2’

}
2.配置litepal.xml文件
在app/src/main 目录下创建一个assets目录,然后在新建litepal.xml,并编辑

<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    <dbname value="BookStore"></dbname>
    <version value="2"></version>
    <list>
    </list>
</litepal>

3.配置LitePalApplication
修改AndroidManifest.xml代码

<application
	android:name="org.litepal.LitePalApplication"
	...>
</application>

5.3 创建和升级数据库

1.定义一个实体类Book.class,并写成员变量作为数据库的每一列的类型,即对象关系映射,且补充其get和set方法。

2.将该类添加到映射模型列表中。
修改litepal.xml

<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    <dbname value="BookStore"></dbname>
    <version value="2"></version>
    <list>
    <mapping class="com.example.litepaltest.Book></mapping>
    </list>
</litepal>

3.创建数据库

Connector.getDatabase();

4.添加新的表
如上,先创建新的类,再添加到映射模型列表中,且版本号加1,重新运行创建语句。

对模型类进行CRUD操作,需要模型类继承DataSupport类。

5.4 使用LitePal添加数据

Book book = new Book();
                book.setName("The Data Code");
                book.setAuthor("Allen");
                book.setPages(454);
                book.setPress("Unknow");
                book.setPrice(46.35);
                book.save();

5.5 使用LitePal更新数据

Book book = new Book();
                book.setPrice(14.95);
                book.setPress("Anchord");
                book.updateAll("name = ? and author = ?", "The Love Story", "Allen");

5.6 使用LitePal删除数据

DataSupport.deleteAll(Book.class, "price < ?", "50");

5.7 使用LitePal查询数据

List<Book> books = DataSupport.findAll(Book.class);

查询Book表第一条数据

Book firstBook = DataSupport.findFirst(Book.class);

查询Book表最后一条数据

Book lastBook = DataSupport.findLast(Book.class);
  • select()方法用于指定查询哪几列数据。
List<Book> books = DataSupport.select("name","author").find(Book.class);
  • where()方法用于指定查询的约束条件。页数大于400.
List<Book> books = DataSupport.where("page > ?", "400").find(Book.class);
  • order()方法用于指定结果的排序方式。价格从高到低。
List<Book> books = DataSupport.order("price desc").find(Book.class);
  • limit()方法用于指定查询结果的数量。只查表前三条。
List<Book> books = DataSupport.limit(3).find(Book.class);
  • offset()方法用于查询结果偏移量,和limit()方法组合使用。查询表第三条第四条第五条。
List<Book> books = DataSupport.limit(3).offset(3).find(Book.class);