关于android数据库框架,有很多种,各有各的优势。
先来看一个图
,但对于批量查询操作,性能最优的莫过于greendao了。今天来说说关于它简单的使用方式。
在3.0以前,还需要用一个java项目来生成session和dao类。但是从3.0开始,则使用编译时注解,在编译时就生成了,方便了很多。
1. 配置gradle
dependencies {
// This is only needed if you want to use encrypted databases
// compile 'net.zetetic:android-database-sqlcipher:3.5.4'//加密用的,这里暂时不用,内部没有64位的包
//greendao
compile 'org.greenrobot:greendao:3.2.0'
}
greendao {
//greendao数据库版本,如果不配置此选项,默认为1
schemaVersion 1
}
2. 创建映射的model,也就是数据表映射类,对象里面的数据则为表字段
@Entity
public class CommunityConfig {
@Id
private Long id;
private int telephone;
private int age;
@Generated(hash = 215426893)
public Config() {
}
@Generated(hash = 418835560)//如果刚刚创建或者更改表需要升级数据库版本,则去掉括号内容
public Config(Long id, int telephone, int age) {
this.id = id;
this.telephone = telephone;
this.age= age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getTelephone() {
return telephone;
}
public void setTelephone(int telephone) {
this.telephone = telephone;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age= age;
}
@Override
public String toString() {
return "Config{" +
"id=" + id +
", telephone=" + telephone +
", age=" + age+
'}';
}
/**
* 设置为默认配置
*/
public void setDefaultData() {
this.telephone = 0;
this.age= 0;
}
}
这样则能够生成一张Config表,字段有id,telephone,age。
3. 使用
1) Application(APP)中,加入全局session初始化。
/**
* 是否加密数据库.
*/
public static final boolean ENCRYPTED = false;
private static DaoSession daoSession;
private final String DB_ENCRYPIED_NAME = "encrypied_db";
private final String DB_NAME = "normal_db";
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
//初始化session
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, ENCRYPTED ? DB_ENCRYPIED_NAME : DB_NAME);
// Database db = ENCRYPTED ? helper.getEncryptedWritableDb(getResources().getString(R.string.db_psw)) : helper.getWritableDb();//如果使用了加密,则需要用密码打开
Database db = helper.getWritableDb();
daoSession = new DaoMaster(db).newSession();//获取到daoSession,用于后续操作
}
/**
* 请求DaoSession
*
* @return
*/
public static DaoSession getDaoSession() {
return daoSession;
}
2)
- 插入insert
ConfigDao configDao = APP.getDaoSession().getConfigDao();
Config config=new Config(null, 1111111111, 11);
configDao.insert(config);//加入
- 删除delete
APP.getDaoSession().getConfigDao().deleteAll();//这样子删除全部条目,也可以删除单个。delete(T entity)。
- 查 query
//查的方式就很多了,这是查全部,放进list
ConfigDao configDao = APP.getDaoSession().getConfigDao();
List<Config> configs = configDao.queryBuilder().build().forCurrentThread().list();//线程安全
if (configs != null && configs.size() != 0) {
return configs.get(0);//取第一个
}
//按条件查找
//eq
dao.queryBuilder().where(Dao.propertys.字段.eq("为什么").unique();//unique得到唯一对象
//like
dao.queryBuilder().where(Dao.propertys.字段.like("值%").list();//like来用于通配符查找,返回集合
//between
dao.queryBuilder().where(Dao.propertys.字段.between(20,30).list();//该字段下,在20到30之间的集合
//gt==》大于
dao.queryBuilder().where(Dao.propertys.字段.gt(20).list();//该字段下,在20之后的集合
//lt==》小于
dao.queryBuilder().where(Dao.propertys.字段.lt(20).list();//该字段下,在20之下的集合
//notEq==》不等于
dao.queryBuilder().where(Dao.propertys.字段.notEq(20).list();//该字段下,不等于20的集合
//ge==》大于等于
dao.queryBuilder().where(Dao.propertys.字段.ge(20).list();//该字段下,大于等于20的集合
//orderAsc
dao.queryBuilder().where(Dao.propertys.字段.eq("为什么").orderAsc(Dao.Properties.字段).list();//该字段等值后再升序排序
- 改 update
//获取到dao操作类
ConfigDao configDao = APP.getDaoSession().getConfigDao();
//查找到要更改的对象
Config config=configDao.queryBuilder().build().forCurrentThread().list().get(0);
config.setAge(00);//重新设置值
configDao.update(config);//更改数据库
具体查看官方api,因为查询用的最多,所以这里查询讲得多一点。
注意:
- 如果升级数据库,原数据库表中数据可以不保存,则使用此框架可以。因为源码中数据库的update,删除了之前的表,再重新创建的,所以不会报错。但是也因此原始数据会造成丢失。
想要做到不删除也是可以的,处理方式如下:
- 在不用更新数据库的时候,注释调相应的配置,这样在同步编译的时候就不会重新生成DaoMaster。需要用的时候再打开它,并更新版本
//apply plugin: 'org.greenrobot.greendao'
//buildscript {
// repositories {
// jcenter()
// mavenCentral()
// }
//
// dependencies {
// classpath 'org.greenrobot:greendao-gradle- plugin:3.2.2' // add plugin
// }
//}
//greendao {
// schemaVersion 4
// daoPackage 'com.xxx.bean.greendao'//这个是生成代码保存的包名
// targetGenDir 'src/main/java'//保存到java代码路径
//}
- 在DaoMaster中处理升级的函数,就类似我们自己写的数据库方式中的升级处理
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
//不删除原表
//dropAllTables(db, true);
//onCreate(db);
for (int i = oldVersion + 1; i <= newVersion; i++) {
switch (i) {//执行对应版本应该做的操作
case 2://增加表
UserDao.createTable(db, false);
break;
}
}
}
2 . 打包混淆问题(打包后的APK,使用不了):
打包后使用不了,debug能使用,很明显,混淆的问题。报错如下:
Caused by: org.greenrobot.greendao.DaoException: Could not init DAOConfig
at org.greenrobot.greendao.internal.DaoConfig.<init>(Unknown Source)
at org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(Unknown Source)
at com.demo.model.h.<init>(Unknown Source)
at com.demo.APP.onCreate(Unknown Source)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4615)
at android.app.ActivityThread.access$1600(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1392)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5318)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:922)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:717)
Caused by: java.lang.NoSuchFieldException: TABLENAME
at java.lang.Class.getField(Class.java:1048)
at org.greenrobot.greendao.internal.DaoConfig.<init>(Unknown Source)
at org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(Unknown Source)
at com.demo.model.h.<init>(Unknown Source)
at com.demo.APP.onCreate(Unknown Source)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4615)
at android.app.ActivityThread.access$1600(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1392)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5318)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:922)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:717)
解决办法只需要在混淆文件中加入下面代码即可:
#greendao3.2.0,此是针对3.2.0,如果是之前的,可能需要更换下包名
-keep class org.greenrobot.greendao.**{*;}
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties