上一篇文章 Android系列之GreenDao基本使用(增、删、改、查)给大家介绍的GreenDao最基本的用法。看完上篇文章之后,大家对于基本的增删改查应该都已经学会了。那么这篇文章主要就是给大家扩展一下,在实际使用中可能会遇到的一些问题。
这里我准备把数据库升级和greenDaoUtils工具类放一起说明。先说下greenDaoUtils工具类吧。这个其实没什么好说的,直接copy代码就可以了。
一共2个类:
这里解释下为什么需要继承DaoMaster.DevOpenHelper(主要是为了数据库升级做准备)重写其中的方法(主要是onUpgrade):
oncreate
:这里是将第二个参数改成了true,原因在注释中写了,不多做介绍。
onUpgrade
更新方法,数据库更新主要是这个方法。我们去掉了父类的方法,因为父类的方法是先drop然后在create,这样会导致数据丢失。
1. MyDaoMaster
package com.gh.greendaodemo.base;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.gh.greendaodemo.gen.DaoMaster;
import org.greenrobot.greendao.database.Database;
import static com.gh.greendaodemo.gen.DaoMaster.SCHEMA_VERSION;
import static com.gh.greendaodemo.gen.DaoMaster.createAllTables;
/**
* @author cj
* @date 2020/04/09
*/
public class MyDaoMaster extends DaoMaster.DevOpenHelper {
public MyDaoMaster(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onCreate(Database db) {
Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
//我就把这里的false修改成了true
//这样 有就不创建表,没有就创建表
//原来的OpenHelper的flase太不灵活了
createAllTables(db, true);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("MyDaoMaster", "oldVersion:" + oldVersion + "-newVersion:" + newVersion);
/*此处不用super,因为父类中包含了
dropAllTables(db, true);
onCreate(db);
需要自己定制升级
*/
}
}
2. DbHelper
package com.gh.greendaodemo.base;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.gh.greendaodemo.gen.DaoMaster;
import com.gh.greendaodemo.gen.DaoSession;
import org.greenrobot.greendao.query.QueryBuilder;
import java.io.File;
import java.io.IOException;
/**
* @author cj
* 使用说明:先在App中init()。然后在需要使用的地方 DbHelper.getInstance().getDaoSession().getXXXXXXXXDao()
*/
public class DbHelper {
private static final String DEFAULT_DATABASE_NAME = "Database.db";
private static DbHelper instance;
private DaoSession mDaoSession;
public static DbHelper getInstance() {
if (null == instance) {
throw new NullPointerException("DbHelper未初始化");
}
return instance;
}
/**
* 初始化,默认的数据名
*/
public static void init(Context context) {
if (null == instance) {
instance = new DbHelper(context, DEFAULT_DATABASE_NAME);
}
}
/**
* 初始化,指定的数据库名
*/
public static void init(Context context, String dbName) {
if (null == instance) {
instance = new DbHelper(context, dbName);
}
}
/**
* 设置greenDao
*/
public static void clear() {
instance = null;
}
private DbHelper(Context context, String dbName) {
//默认是data/data/应用包名/databases 下的
MyDaoMaster helper = new MyDaoMaster(context, dbName, null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
mDaoSession = daoMaster.newSession();
//sql日志
QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;
}
public DaoSession getDaoSession() {
return mDaoSession;
}
}
使用:
DbHelper.getInstance().getDaoSession().getUserInfoTableDao().insert(userInfoTable);
想了许久,本来想自己写个升级的方法,类似与网上的先保存数据,然后删除表、在新增表。感觉这样实在是太麻烦了。后续在github上找到了一个开源的升级工具类,最终还是决定用这个工具类。
GreenDaoUpgradeHelper
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies {
compile 'org.greenrobot:greendao:3.2.0'
compile 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("MyDaoMaster", "oldVersion:" + oldVersion + "-newVersion:" + newVersion);
/*此处不用super,因为父类中包含了
dropAllTables(db, true);
onCreate(db);
需要自己定制升级
*/
MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {
@Override
public void onCreateAllTables(Database db, boolean ifNotExists) {
DaoMaster.createAllTables(db, ifNotExists);
}
@Override
public void onDropAllTables(Database db, boolean ifExists) {
DaoMaster.dropAllTables(db, ifExists);
}
}, UserInfoTableDao.class, TeacherUserMergeDao.class, TeacherInfoTableDao.class);
}
4 查看日志:
如果你想查看日志信息,请将DEBUG设置为true
MigrationHelper.DEBUG = true;
那么我们如何来验证呢?首先先给大家推荐一个sqlite的可视化工具。为什么推荐这个工具呢,之前查看数据怎么查看的?先从设备里面拷贝出来sqlite,然后保存到本地,在从本地打开。这样的操作其实还频繁的,而且也比较耗时。有没有一种更好的方式来查看sqlite呢?请看这里:Android-Debug-Database
这个可以在网页上查看sqlite的表和数据,附上几张图:
//greenDao 调试工具
debugImplementation 'com.amitshekhar.android:debug-db:1.0.0'
打开命令行,运行
adb forward tcp:8080 tcp:8080
ok至此,数据库升级和数据库可视化工具都已经完成啦,下一步要验证数据库升级有没有作用?感兴趣的同学可以自己验证下,我自己验证了没问题的(你可以新增一个字段,然后在可视化中看看有没有新增,同时注意数据有没有删除)。
GreenDao有加密的接口,使用非常方便,在GreenDao初始化的时候启动加密模式:
一般模式:
//获取可写数据库
SQLiteDatabase db = dbHelper.getWritableDatabase();
//获取可读数据库
SQLiteDatabase db = dbHelper.getReadableDatabase();
加密模式:
//获取写数据库
SQLiteDatabase db = dbHelper.getWritableDatabase(key);
//获取可读数据库
SQLiteDatabase db = dbHelper.getReadableDatabase(key);
GreenDao自己自带加密的接口,但是需要自己导入依赖包:
implementation'net.zetetic:android-database-sqlcipher:3.5.7'
修改上面的DbHelper类:
/**
* 是否加密
*/
public static boolean ENCRYPTED = true;
private static final String PASSWORD = "123456";
/**
* 初始化,指定的数据库名是否需要加密
*/
public static void init(Context context, String dbName, boolean needEncrypted) {
if (null == instance) {
ENCRYPTED = needEncrypted;
instance = new DbHelper(context, dbName);
}
}
private DbHelper(Context context, String dbName) {
MyDaoMaster helper = new MyDaoMaster(context, dbName, null);
Database db;
if (ENCRYPTED) {
db = helper.getEncryptedWritableDb(PASSWORD);
} else {
db = helper.getWritableDb();
}
DaoMaster daoMaster = new DaoMaster(db);
mDaoSession = daoMaster.newSession();
//sql日志
QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;
}
这样就ok了,我们在web上啥都看不到了。。。。
下载db文件,发现都打不开了,完美~
我个人建议在开发的过程中不需要进行加密操作,不然自己调试的时候,都没法看到具体的数据,包括数据的升级也是,自己调试,不需要重写update这个方法。到发布的时候,才需要考虑数据库的升级和加密。
附:
GreenDao三部曲:
Android系列之GreenDao基本使用(增、删、改、查)(一)
Android系列之GreenDao连表查询(二)
Android系列之GreenDao数据升级和加密(三)