文章目录
1.背景
做Android app开发,数据持久化,即数据存储的场景是一定会遇到的。选择SQLite数据库存储数据是常见方式之一。
SQLite的使用并不是一件很复杂的事,一般集成使用SQLite的方式有2种:
一是完全自定义SQLiteOpenHelper,封装DatabaseManager,业务及事务处理大量使用sql语句。这样的情况适合有一定sql基础的同学,且有一定的代码工作量,有时候容易出错(特别是sql语句相关),好处就是完全做到自己能控制,方便掌握细节,进行性能调优等等。
另外一种方式就是使用第三方相关的ORM(对象/关系映射)框架来协助管理操作数据库,将Java对象映射到 SQLite 数据库中。这种方式我们不需要编写复杂的 SQL语句,适合新手,或中小型项目快速完成开发。同时不用考虑并发等数据库操作问题。ORM 框架有很多,比较著名的有OrmLite、greenDAO、ObjectBox、Realm等。我前2种都用过,比较推荐greenDAO。 在性能方面,greenDAO针对 Android 进行了高度优化, 最小的内存开销 、依赖体积小,同时还是支持数据库加密。最主要是封装涵盖了大部分sql的关键词的方法,且在联表查询以及支持运行自定义sql语句方面都很友好。
2.原生使用方式及相关知识点
我以前在多个项目中都采用自定义SQLiteOpenHelper,封装DatabaseManager这种方式来实现我的数据存储部分。这篇文章中我就不再赘述基本使用方法。我列出几点我认为需要弄清楚的关键知识点。
- SQLiteOpenHelper实际上是一个数据库连接类,极强列建议一个数据库对应一个SQLiteOpenHelper,否则同一时间用不同的数据库连接来对同一个数据库进行写操作的话,那么除第一个,其余都会失败。常见错误android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5) 的原因就是这个。
- SQLiteDatabase是一个数据库对象,封装了一些操作数据库的api。比如添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD),对应 insert()、query()、update()、delete()。这些方法更适合新手同学,或处理简单业务逻辑快速开发。我们应该重点掌握execSQL()和rawQuery()方法。execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句。rawQuery()方法用于执行select语句。我更愿意直接通过sql语句完成我们的业务处理。
- 我们在很多demo中看到,数据库在每一次操作后都及时关闭了。但如果单例SQLiteOpenHelper,多线程同时操作数据库时,则会遇到java.lang.IllegalStateException: attempt to re-open an already-closed object错误。即后一个线程在进行时数据任务操作时,前一个线程已经将数据库连接关闭。这时我们常在封装的DatabaseManager内,自己计数,实现数据库缓关闭。
//记数器
private static int mCount;
public synchronized SQLiteDatabase openDb(){
if(mCount==0){
db=helper.getWritableDatabase();
}
mCount++;
return db;
}
public synchronized void CloseDb(){
mCount--;
if(mCount==0){
db.close();
}
}
- 数据库升级部分,是需要从第一个版本开始就注意的。在onUpgrade方法中要针对处于不同版本的数据库进行差异化处理。并且一定记得这种升级的覆盖测试要做到位。不要对自己的代码太盲目自信。
- 非常建议对数据库的最基础的操作方法进行封装,比如封装在DatabaseManager类中。或者基于自己的业务进行一些隔离(接口)层级封装,方便后期更换数据库操作库,或者其他改动。
- 关于基本使用方法,以及CRUD各方法的各类参数的详细解析,以及Cursor的相关方法的分析,我推荐这篇文章:基本用法(请点击)
3.ORM框架方式——greenDAO使用
1.greenDAO简介
greenDAO 是一款开源的面向 Android 的轻便、快捷的 ORM 框架。通过greenDAO,我们可以非常便捷的将Java 对象映射到 SQLite 数据库中保存。
2.greenDAO优势
- 持续维护更新
团队从2011年持续维护更新项目,最后一次代码提交是今年9月9号。并且该库被很多知名app应用。 - 高性能
这是一张放在greenDAO官网的图,应该是每秒对于entity的操作频次,性能数据。是greenDAO、OrmLite、ActiveAndroid这三个ORM框架的比较。 - 轻量级
GreenDao 核心库小于150k,只是jar包,并且没有native部分。 - 支持 protocol buffer(protobuf) 协议
GreenDao 支持 protocol buffer(protobuf) 协议数据的直接存储,如果你通过 protobuf 协议与服务器交互,将不需要任何的映射。 - 快速
除了库的性能效率快速以外,通过注解智能生成DAO类代码的方式,以及封装了大量易于使用的强大API等方面,减少工作量,大大提高开发效率。 - 数据加密
greenDAO支持SQLCipher加密数据库,以确保用户的数据安全。
3.build.gradle文件
greendao {
schemaVersion 1 //数据库版本号
daoPackage 'com.hsj.db.dao' // 设置DaoMaster、DaoSession、Dao 包名
targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录
generateTests false //设置为true以自动生成单元测试。
targetGenDirTests 'src/main/java' //应存储生成的单元测试的基本目录。默认为 src / androidTest / java。
}
4.核心类介绍
-
DaoMaster
DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的DAO类(而不是对象),它有静态方法来创建表或删除它们。它的内部类OpenHelper和DevOpenHelper是SQLiteOpenHelper实现,我们可以通过它们创建不同模式的 SQLite 数据库。 -
DaoSession
管理特定模式的所有可用DAO对象,您可以使用其中一个getter方法获取该对象。DaoSession还提供了一些通用的持久性方法,如实体的插入,加载,更新,刷新和删除。 -
XyzDAO
数据访问对象(DAO)持久存在并查询实体。greenDAO 会根据每个实体类的注解生成一个与之对应DAO对象。它具有比DaoSession更多的持久性方法,例如:count,loadAll和insertInTx。 -
XyzEntity
可持久化对象。通常, 实体对象代表一个数据库行使用标准 Java 属性(如一个POJO 或 JavaBean )。核心类之间的关系:
5.注解详解
greenDAO常用注解有这么些:
- @Entity
@Entity是greenDao必不可少的注解,只有在实体类中使用了@Entity注解greenDao才会创建对应的表。当然我们也可以使用@Entity配置一些细节,源码如下:
public @interface Entity {
/**
* 在数据库中使用的别名,默认使用的是实体的类名.
*/
String nameInDb() default "";
/**
* 定义索引,可以跨越多个列。
*/
Index[] indexes() default {
};