[Android][第一行代码][第 6 章 数据存储]
2017-09-15 14:36
411 查看
01. 持久化简介
瞬时数据就是指那些存储在内存当中,有可能会因为程序关闭或其他原因导致内存被回收而丢失的数据。持久化数据就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失。
02. 文件存储
文件存储不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中。因而比较适合用于存储一些简单的文本数据或二进制数据。通过
Context提供的
openFileOutput()方法将文件存入内部存储路径中。操作模式
Context.MODE_PRIVATE默认模式私有且覆盖
Context.MODE_APPEND模式每次写入数据进行追加
通过
Context提供的
openFileInput()方法用于从文件中进行数据读取。
存数据
/** * 保存数据到内部存储文件 * * @param fileName 文件名称 * @param saveData 写入的数据 */ private void saveToFile(String fileName, String saveData) { FileOutputStream fileOutputStream = null; BufferedWriter bufferedWriter = null; try { fileOutputStream = this.openFileOutput(fileName, Context.MODE_APPEND);// [/data/data/com.just.first/files] bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream)); bufferedWriter.write(saveData); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bufferedWriter != null) { bufferedWriter.close(); } if (fileOutputStream != null) { fileOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
取数据
/** * 从内部存储文件中读取数据 * * @param fileName 文件名称 * @return 文件内容 */ private String loadFromFile(String fileName) { FileInputStream fileInputStream = null; BufferedReader bufferedReader = null; StringBuilder dataContent = new StringBuilder(); try { fileInputStream = this.openFileInput(fileName); bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream)); String line = ""; while ((line = bufferedReader.readLine()) != null) { dataContent.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (bufferedReader != null) { bufferedReader.close(); } if (fileInputStream != null) { fileInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } return dataContent.toString(); }
03. SharedPreferences
SharedPreferences使用键值对的方式存储数据。支持
多种不同的
数据类型存储。
文件存储路径
/data/data/主包名/shared_prefs
文件存储的是
xml文件。
获取
sharedPreferences实例的三种方法
通过
Context类的
getSharedPreferences(String name, int mode)方法获取。
第一个参数文件名称
第二个参数模式
通过
Activity类的
getPreferences(int mode)方法获取。
一个参数模式
文件名称会自动获取当前活动类名
getLocalClassName()
通过
PreferenceManager类的
getDefaultSharedPreferences(Context context)方法获取。
一个参数上下文
文件名称会自动获取当前程序主包名
context.getPackageName() + "_preferences"
存储数据需要三个步骤
获取
SharedPreferences.Editor对象
通过
Editor对象进行数据的添加
调用
Editor的
apply()方法进行数据的提交
存数据
/** * 将数据保存到 SharedPreferences * * @param fileName 文件名 * @param keyWord 键 * @param saveData 值 */ private void saveToSharedPreferences(String fileName, String keyWord, String saveData) { SharedPreferences sharedPreferences = this.getSharedPreferences(fileName, MODE_APPEND); SharedPreferences.Editor edit = sharedPreferences.edit(); edit.putString(keyWord, saveData); edit.apply(); }
取数据
/** * 从 SharedPreferences 加载数据 * * @param fileName 文件名 * @param keyWord 键 * @return 值 */ private String loadFromSharedPreferences(String fileName, String keyWord) { SharedPreferences sharedPreferences = this.getSharedPreferences(fileName, MODE_APPEND); return sharedPreferences.getString(keyWord, null);// 默认值 }
数据的写入和读取均可以根据类型进行操作。
04. SQLite 数据库
SQLite数据库是一款轻量级的关系型数据库,运算速度快,占用资源少。支持标准 SQL 语法,遵循数据库的 ACID 事务。
自定义
SQLiteOpenHelper继承系统
SQLiteOpenHelper
/** * SQLiteOpenHelper 实现数据库创建与升级 * * @author JustDo23 */ public class BookOpenHelper extends SQLiteOpenHelper { /** * 构造方法[必须实现] * * @param context 上下文 * @param name 数据库名称[带上后缀 .db] * @param factory 工厂[允许数据查询使用自定义 Cursor][一般传 null] * @param version 版本[整型] */ public BookOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, "BookStore" + ".db", null, 1); } /** * 创建数据表方法[必须实现] * * @param db 数据库操作对象 */ @Override public void onCreate(SQLiteDatabase db) { String sql = "create table Book ( " + "id integer primary key autoincrement" + ", " + "author text" + ", " + "price real" + ", " + "pages integer" + ", " + "name text" + ")"; db.execSQL(sql);// 执行 SQL 语句 } /** * 数据库升级方法[必须实现] * * @param db 数据库操作对象 * @param oldVersion 旧的版本号 * @param newVersion 新的版本号 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
数据库文件存储路径
/data/data/主包名/databases
注意:SQL 语句中相应位置的空格及分割符很重要
数据类型
integer表示整型
real表示浮点型
text表示文本类型
blob表示二进制类型
primary key表示主键
autoincrement表示自增长
数据库的创建
继承系统
SQLiteOpenHelper并实现相应方法后并没有实现数据库的创建
在
SQLiteOpenHelper中有两个重要的方法
getReadableDatabase()获取读数据操作的对象
getWritableDatabase()获取写数据操作的对象
这两个方法可以创建或打开一个数据库。数据库存在则直接打开,数据库不存在则创建并打开。
这两个方法返回的对象都可以对数据库进行读写操作。
当数据不可写入时候如磁盘空间已满,
getReadableDatabase()方法将以只读方式打开数据库,
getWritableDatabase()方法会抛出异常。
ADB 调试工具
进入 Shell 内核
$ adb shell
打开数据库
$ sqlite3 BookStore.db
查看数据库中的数据表
$ .table
数据表
android_metadata是每个数据库自动生成的
查看建表语句
$ .schema
退出
$ .exit $ .quit
05. 数据库操作
升级数据库/** * 数据库升级方法 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists Book");// 删除原来的表 onCreate(db);// 重新进行创建 }
先将已经存在的数据表进行删除,然后创建新的表。数据表不能重复创建,否则会崩溃。
修改构造方法中的数据库版本号。
概述
数据库操作有 4 种简称
CRUD
C代表
Create添加
insert
R代表
Retrieve查询
select
U代表
Update更新
update
D代表
Delete删除
delete
添加数据
利用
SQLiteDatabase对象的
insert(String table, String nullColumnHack, ContentValues values)方法进行数据数据添加
第一个参数表名
第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值 NULL 一般传入 null 即可
第三个参数数据集合键值对关系键为列名因此值为数据
public void insert() { SQLiteDatabase writableDatabase = bookOpenHelper.getWritableDatabase();// 获取数据操作对象 ContentValues contentValues = new ContentValues();// 键值对集合 contentValues.put("name", "FirstLine");// 列名-数据 contentValues.put("author", "Guo"); contentValues.put("pages", "570"); contentValues.put("price", 79.0); writableDatabase.insert("Book", null, contentValues);// 指定表名添加 }
数据库的查询语句
$ select * from Book;
更新数据
利用
SQLiteDatabase对象的
update(String table, ContentValues values, String whereClause, String[] whereArgs)方法进行数据数据更新
后两个参数用于约束更新某一行或者某几行的数据,不指定默认更新所有行。
第三个参数对应 SQL 语句的 where 部分其中
?代表占位符
第四个参数按照先后顺序对应为占位符进行赋值
public void update() { SQLiteDatabase writableDatabase = bookOpenHelper.getWritableDatabase();// 获取数据操作对象 ContentValues contentValues = new ContentValues();// 键值对集合 contentValues.put("price", 99.9); writableDatabase.update("Book", contentValues, "name = ?", new String[]{"FirstLine"}); }
删除数据
利用
SQLiteDatabase对象的
delete(String table, String whereClause, String[] whereArgs)方法进行数据数据删除
public void delete() { SQLiteDatabase writableDatabase = bookOpenHelper.getWritableDatabase();// 获取数据操作对象 writableDatabase.delete("Book", "name = ?", new String[]{"FirstLine"}); }
查询数据
SQL的全称是
Structured Query Language即
结构化查询语言
利用
SQLiteDatabase对象的
query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)方法进行数据数据查询
query()重载函数比较多功能与 SQL 语句中的查询类似
query方法参数 | 对应 SQL 部分 | 描述 |
---|---|---|
table | from table_name | 指定查询的表名 |
columns | select column1, column2 | 指定查询的列名 |
selection | where column = value | 指定 where 的约束条件 |
selectionArgs | - | 为 where 中的占位符提供具体的值 |
groupBy | group by column | 指定需要 group by 的列 |
having | having column = value | 对 group by 后的结果进一步约束 |
orderBy | order by column1, column2 | 指定查询结果的排序方式 |
public void query() { SQLiteDatabase readableDatabase = bookOpenHelper.getReadableDatabase();// 获取数据操作对象 Cursor cursor = readableDatabase.query("Book", null, null, null, null, null, null);// 查询获得游标 if (cursor.moveToFirst()) {// 是否可以移动位置 do { String author = cursor.getString(cursor.getColumnIndex("author")); String name = cursor.getString(cursor.getColumnIndex("name")); String pages = cursor.getString(cursor.getColumnIndex("pages")); String price = cursor.getString(cursor.getColumnIndex("price")); LogUtils.e("Book: " + author + " -- " + name + " -- " + pages + " -- " + price); } while (cursor.moveToNext());// 是否可以继续往下移动 } }
使用 SQL 语句
添加数据
writableDatabase.execSQL("insert into Book (name, author, pages, price) values (?, ?, ?, ?)", new String[]{"SecondLine", "Lin", "123", "66.6"});writableDatabase.execSQL("insert into Book (name, author, pages, price) values (?, ?, ?, ?)", new String[]{"SecondLine", "Lin", "123", "66.6"});
更新数据
writableDatabase.execSQL("update Book set pages = ? where author = ?", new String[]{"333", "Lin"});writableDatabase.execSQL("update Book set pages = ? where author = ?", new String[]{"333", "Lin"});
删除数据
writableDatabase.execSQL("delete from Book where pages > ?", new String[]{"10"});
查询数据
readableDatabase.rawQuery("select * from Book", null);// 查询获得游标
06. LitePal 数据库
LitePal 采用了对象关系映射 ORM 的模式。简单说,我们使用的编程语言是面向对象语言,而使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射了。因此,可以用面向对象的思维来操作数据库,而不用再和 SQL 语句打交道。GitHub 链接https://github.com/LitePalFramework/LitePal
使用步骤
添加依赖
创建
assets文件夹
创建
litepal.xml配置文件
在
Application中进行初始化
创建实体类也就是表结构
配置
litepal.xml文件
创建数据库
LitePal.getDatabase();// 使用 LitePal 创建数据库
添加数据
实体类需要要继承
DataSupport类
直接调用实体类的
save()方法
Book book = new Book();// 实例化实体类 book.save();// 使用 LitePal 插入数据
更新数据
通过对已存储的对象重新设值后重新调用
save()方法来更新。
调用
model.isSaved()方法返回
true则表示已存储的对象。一种是调用过
save()方法的对象,一种是通过
LitePal的
查询 API得到的对象。
Book book = new Book();// 实例化实体类 book.save();// 使用 LitePal 插入数据
book.setPages("324");// 更新数据
book.save();// 对插入的数据进行更新
通过任意对象设置需要更新的值后调用
updateAll(String... conditions)方法来更新
第一个参数可以指定条件约束,不指定代表更新所有
注意:将某个字段设置为默认值需要调用
setToDefault(String fieldName)参数字段名
Book book = new Book();// 实例化实体类 book.setPages("776");// 更新数据 book.setToDefault("price");// 设置默认值 book.updateAll("name = ? and pages = ?", "老人与海", "76");
删除数据
通过调用已存储的对象的
delete()方法来删除
直接使用
DataSupport.deleteAll()传递参数进行删除,传递表名及约束,不传则删除所有
DataSupport.deleteAll(Book.class, "pages < ?", "400");// 指定表名及约束进行删除
查询数据
直接使用
DataSupport类中的相关方法进行查询
查询所有
DataSupport.findAll(Book.class);// 查询所有 DataSupport.findFirst(Book.class);// 查询第一条 DataSupport.findLast(Book.class);// 查询最后一条
更多查询功能
DataSupport.select("name", "author", "pages")// 指定查询的列 .where("pages > ?", "400")// 指定查询的约束条件 .order("pages desc")// 指定查询结果排序 .limit(10)// 指定查询结果数量 .offset(2)// 指定查询结果偏移-抛弃前2条 .find(Book.class);// 指定查询的表名
select()方法用于指定查询哪几列的数据
where()方法用于指定查询的约束条件
order()方法用于指定查询结果的排序方式 另
desc表示降序
asc表示升序
limit()方法用于指定查询结果的数量
offset()方法用于指定查询结果偏移量
07. 小结
文件存储核心是Java中的
I/O 流操作因此需要进行复习练习。
注意
SharedPreferences提交
apply()方法与
commit()方法。
数据库的原生 API 使用及一些第三方库的使用。
数据库操作对象及游标对象等在使用结束后一定要进行关闭。
相关文章推荐
- 《第一行代码--Android》读书笔记之数据存储
- 【第一行代码】Android数据存储
- 【第一行代码-Android】学习(一)及在studio的迁移(5)存储数据
- Android第一行代码学习笔记四----数据存储
- 数据存储之SharedPreferences存储——第一行代码Android学习笔记
- 第一行代码 第六章 数据储存方案 - 文件存储
- 第一行代码-第6章 数据存储方案,持久化技术
- 安卓第一行代码之数据存储
- 【android】:android数据存储之sharedPreferences代码可使用
- android SD卡 数据存储代码
- 第一行代码 第六章 数据储存方案 - LitePal数据库存储
- 第一行代码笔记3:数据存储
- 第一行代码笔记,第六章-----详解数据存储
- 第一行代码 第六章 数据储存方案 - SQLite数据库存储
- Android——数据存储(课堂代码整理:SharedPreferences存储和手机内部文件存储)
- 第一行代码笔记 数据存储全方案
- android第一行代码-3.activity之间的调用跟数据传递
- 数据存储之SQLite 数据库存储——第一行代码Android学习笔记
- 数据存储之文件存储——第一行代码Android学习笔记
- Android第一行代码 第九章 数据解析方式(xml,json)