Android系列之GreenDao数据升级和加密(三)

背景

上一篇文章 Android系列之GreenDao基本使用(增、删、改、查)给大家介绍的GreenDao最基本的用法。看完上篇文章之后,大家对于基本的增删改查应该都已经学会了。那么这篇文章主要就是给大家扩展一下,在实际使用中可能会遇到的一些问题。

  1. 优化:新建一个GreenDapUtils类,帮助我们获取daoSession。总不能每次都new一个daoSession。
  2. 数据库升级是怎么样的逻辑?
  3. app部署之后,如果需要对sql进行加密的话,GreenDao有对应的方法么?
  4. 如何更加优雅的查看sqlite?

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);

GreenDao数据库升级

想了许久,本来想自己写个升级的方法,类似与网上的先保存数据,然后删除表、在新增表。感觉这样实在是太麻烦了。后续在github上找到了一个开源的升级工具类,最终还是决定用这个工具类。
GreenDaoUpgradeHelper

GreenDaoUpgradeHelper

  1. 导入依赖
    在根目录的build.gradle文件的repositories内添加如下代码
allprojects {
		repositories {
			...
			maven { url "https://jitpack.io" }
		}
	}
  1. 添加依赖(greendao 3.0及以上)
	dependencies {
	        compile 'org.greenrobot:greendao:3.2.0'
	        compile 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
	}
  1. 添加一个新类继承DaoMaster.OpenHelper,添加构造函数并实现onUpgrade方法,在onUpgrade方法添加如下代码即可,参数为所有的Dao类:
	 @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; 

SQLLite可视化工具(Android-Debug-Database)

那么我们如何来验证呢?首先先给大家推荐一个sqlite的可视化工具。为什么推荐这个工具呢,之前查看数据怎么查看的?先从设备里面拷贝出来sqlite,然后保存到本地,在从本地打开。这样的操作其实还频繁的,而且也比较耗时。有没有一种更好的方式来查看sqlite呢?请看这里:Android-Debug-Database
这个可以在网页上查看sqlite的表和数据,附上几张图:
在这里插入图片描述

安装步骤

  1. 导入依赖:
 	//greenDao 调试工具
    debugImplementation 'com.amitshekhar.android:debug-db:1.0.0'
  1. 启动项目:查看log日志:
    在这里插入图片描述
    这里会打印访问的地址。
    我这里是有问题的,打印的是0.0.0.0:8080。
    解决方案:
    打开命令行,运行
    adb forward tcp:8080 tcp:8080
    重启app。然后打开浏览器输入 http://localhost:8080 就好啦

问题:如何指定网页的端口:

在这里插入图片描述
ok至此,数据库升级和数据库可视化工具都已经完成啦,下一步要验证数据库升级有没有作用?感兴趣的同学可以自己验证下,我自己验证了没问题的(你可以新增一个字段,然后在可视化中看看有没有新增,同时注意数据有没有删除)。

GreenDao数据加密

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这个方法。到发布的时候,才需要考虑数据库的升级和加密。

总结

  1. 数据库升级:GreenDaoUpgradeHelper主要是重写onUpdate方法,将原来drop->create 变成工具类的方法。
  2. 数据库加密:采用sqlcipher进行加密,GreenDao中已经自带了接口,只需要导入包就可以。
  3. 数据库的可视化:Android-Debug-Database。唯一注意的是出现0.0.0.0:8080要将设备的端口和本地的端口映射起来。

附:
GreenDao三部曲:
Android系列之GreenDao基本使用(增、删、改、查)(一)
Android系列之GreenDao连表查询(二)
Android系列之GreenDao数据升级和加密(三)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,GreenDAO支持数据库加密。你可以通过在DaoMaster类中使用SQLCipher来加密数据库。SQLCipher是一个基于SQLite的开源库,可用于加密SQLite数据库。 以下是使用SQLCipher加密GreenDAO数据库的步骤: 1. 在build.gradle文件中添加SQLCipher库的依赖: ``` dependencies { implementation 'net.zetetic:android-database-sqlcipher:4.4.0' } ``` 2. 在DaoMaster类中使用SQLCipher初始化数据库。你需要在使用SQLiteOpenHelper创建数据库之前,调用SQLiteDatabase.loadLibs(context)加载SQLCipher库,并在创建数据库时,指定加密密码。 ```java public class MyDaoMaster extends DaoMaster.OpenHelper { public MyDaoMaster(Context context, String name) { super(context, name); SQLiteDatabase.loadLibs(context); } public MyDaoMaster(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); SQLiteDatabase.loadLibs(context); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { super.onUpgrade(db, oldVersion, newVersion); // 数据库升级时,需要重新加密数据 db.execSQL("PRAGMA cipher_migrate;"); } @Override public SQLiteDatabase getWritableDatabase() { SQLiteDatabase db = super.getWritableDatabase(SQLCipherUtils.getEncryptionKey()); // 开启数据库加密 db.rawExecSQL("PRAGMA key = '"+SQLCipherUtils.getEncryptionKey()+"';"); db.rawExecSQL("PRAGMA cipher_use_hmac = off;"); db.rawExecSQL("PRAGMA cipher_page_size = 1024;"); db.rawExecSQL("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;"); db.rawExecSQL("PRAGMA cipher_hmac_algorithm = HMAC_SHA1;"); return db; } } ``` 3. 在Application类中初始化GreenDAO。你需要使用自定义的MyDaoMaster类,以及指定数据库名称和版本号。 ```java public class MyApplication extends Application { private DaoSession daoSession; @Override public void onCreate() { super.onCreate(); // 初始化GreenDAO DaoMaster.DevOpenHelper helper = new MyDaoMaster(this, "my-db"); Database db = helper.getEncryptedWritableDb(SQLCipherUtils.getEncryptionKey()); daoSession = new DaoMaster(db).newSession(); } public DaoSession getDaoSession() { return daoSession; } } ``` 需要注意的是,加密密码需要妥善保管,不要轻易泄露。你可以通过SQLCipherUtils类来生成加密密码,以及验证密码是否正确。 ```java public class SQLCipherUtils { private static final String KEY = "my-secret-key"; public static String getEncryptionKey() { return KEY; } public static boolean isPasswordCorrect(String password) { return password != null && password.equals(KEY); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值