GreenDao加密与更新升级

前言:

上一篇简介了greendao的数据库的接入以及简单的操作,既然涉及到数据库中的数据,那就必须考虑到加密问题了,可能有些隐秘的数据不能直接加密,我们就需要使用加密了。一旦我们数据库结构改变了,我们就需要使用数据库更新了。

一:数据库加密

我们这里使用sqlcipher加密greendao数据库:

1:在使用GreenDao的Moudle中添加依赖:

//数据库加密库

compile'net.zetetic:android-database-sqlcipher:3.5.6'

2:在初始化数据库中我们只需要获取一个加密的数据库即可

/**

*配置数据库

*/

//数据库是否加密

public static final boolean ENCRYPTED=false;

private voidsetupDatabase() {

//创建数据库book.db"

 DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "book.db", null);

//获取可写数据库 如果ENCRYPTED=true获取加密数据库  password为加密的密码

Database db =ENCRYPTED? helper.getEncryptedWritableDb("password") : helper.getWritableDb();

//获取数据库对象

DaoMaster daoMaster =newDaoMaster(db);

//获取Dao对象管理者

daoSession= daoMaster.newSession();

}

只需要以上2步我们就完成了对数据库的加密

二:对GreenDao数据库进行升级

在greendao数据库初始化的过程中我们使用的是DaoMaster.DevOpenHelper来获取helper对象来创建数据库:我们可以看到里面的源码:

DevOpenHelper

上面我们可以看到WARNING:更新会删除所有的数据库重写创建,并不会保存之前的数据库数据,因此只是有与开发阶段使用。

因此我们在项目上线之后我们就不能使用这种方式创建数据库了,我们需要做的是自己创建一个OpenHelper去创建数据库,在onUpgrade方法中恢复数据:

1:创建一个和原来表一样的临时表

2:删除之前的数据库,并且创建新的数据库。

3:最后恢复临时表的数据到新的数据库中

这样就可以保证数据库里面的数据不会被删除了。

1:创建MergeOpenHelper继承自OpenHelper

public class MergeOpenHelper  extends  DaoMaster.OpenHelper {

public   MergeOpenHelper(Context context,String name) {

super(context,name);

}

public  MergeOpenHelper(Context context,String name,SQLiteDatabase.CursorFactory factory) {

super(context,name,factory);

}

@Override

public voidon Upgrade(Database db, intoldVersion, intnewVersion) {

//super.onUpgrade(db, oldVersion, newVersion);

MigrationHelper.getInstance().migrate(db,UserDao.class,PersonDao.class,BookDao.class);

}

}

2:创建一个合并类,这里拷贝一份大神的代码:

public classMigrationHelper{

private static fina  lString  CONVERSION_CLASS_NOT_FOUND_EXCEPTION="MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";

private static  MigrationHelper  instance;

public static  MigrationHelper  getInstance() {

if(instance==null) {

instance=new  MigrationHelper();

}

return  instance;

}

private static  ListgetColumns(Database db,String tableName) {

List columns =new ArrayList<>();

Cursor cursor =null;

try{

cursor = db.rawQuery("SELECT * FROM "+ tableName +" limit 1", null);

if(cursor !=null) {

columns =new  ArrayList<>(Arrays.asList(cursor.getColumnNames()));

}

}catch(Exception e) {

Log.v(tableName,e.getMessage(),e);

e.printStackTrace();

}finally{

if(cursor !=null)

cursor.close();

}

returncolumns;

}

public void  migrate(Database db,Class>... daoClasses) {

generateTempTables(db,daoClasses);

DaoMaster.dropAllTables(db, true);

DaoMaster.createAllTables(db, false);

restoreData(db,daoClasses);

}

private void  generateTempTables(Database db,Class>... daoClasses) {

for(inti =0;i < daoClasses.length;i++) {

DaoConfig daoConfig =new DaoConfig(db,daoClasses[i]);

String divider ="";

String tableName = daoConfig.tablename;

String tempTableName = daoConfig.tablename.concat("_TEMP");

ArrayList properties =newArrayList<>();

StringBuilder createTableStringBuilder =newStringBuilder();

createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");

for(intj =0;j < daoConfig.properties.length;j++) {

String columnName = daoConfig.properties[j].columnName;

if(getColumns(db,tableName).contains(columnName)) {

properties.add(columnName);

String type =null;

try{

type = getTypeByClass(daoConfig.properties[j].type);

}catch(Exception exception) {

exception.printStackTrace();

}

createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

if(daoConfig.properties[j].primaryKey) {

createTableStringBuilder.append(" PRIMARY KEY");

}

divider =",";

}

}

createTableStringBuilder.append(");");

db.execSQL(createTableStringBuilder.toString());

StringBuilder insertTableStringBuilder =newStringBuilder();

insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");

insertTableStringBuilder.append(TextUtils.join(",",properties));

insertTableStringBuilder.append(") SELECT ");

insertTableStringBuilder.append(TextUtils.join(",",properties));

insertTableStringBuilder.append(" FROM ").append(tableName).append(";");

db.execSQL(insertTableStringBuilder.toString());

}

}

private void restoreData(Database db,Class>... daoClasses) {

for(inti =0;i < daoClasses.length;i++) {

DaoConfig daoConfig =new DaoConfig(db,daoClasses[i]);

String tableName = daoConfig.tablename;

String tempTableName = daoConfig.tablename.concat("_TEMP");

ArrayList properties =new ArrayList();

ArrayList propertiesQuery =new ArrayList();

for(intj =0;j < daoConfig.properties.length;j++) {

String columnName = daoConfig.properties[j].columnName;

if(getColumns(db,tempTableName).contains(columnName)) {

properties.add(columnName);

propertiesQuery.add(columnName);

}else{

try{

if(getTypeByClass(daoConfig.properties[j].type).equals("INTEGER")) {

propertiesQuery.add("0 as "+ columnName);

properties.add(columnName);

}

}catch(Exception e) {

e.printStackTrace();

}

}

}

StringBuilder insertTableStringBuilder =newStringBuilder();

insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");

insertTableStringBuilder.append(TextUtils.join(",",properties));

insertTableStringBuilder.append(") SELECT ");

insertTableStringBuilder.append(TextUtils.join(",",propertiesQuery));

insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

StringBuilder dropTableStringBuilder =newStringBuilder();

dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);

db.execSQL(insertTableStringBuilder.toString());

db.execSQL(dropTableStringBuilder.toString());

}

}

privateStringgetTypeByClass(Class type)throwsException {

if(type.equals(String.class)) {

return"TEXT";

}

if(type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class) || type.equals(int.class)) {

return"INTEGER";

}

if(type.equals(Boolean.class) || type.equals(boolean.class)) {

return"BOOLEAN";

}

Exception exception =newException(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));

exception.printStackTrace();

throwexception;

}

}

3:修改初始化数据库代码

/**

*配置数据库

*/

private voidsetupDatabase() {

//创建数据库book.db"  这里使用了升级使用的OpenHelper

MergeOpenHelper helper =newMergeOpenHelper(this,"book.db");

//获取可写数据库

Database db =ENCRYPTED? helper.getEncryptedWritableDb("password") : helper.getWritableDb();

//SQLiteDatabase db = helper.getWritableDatabase();

//获取数据库对象

DaoMaster daoMaster =newDaoMaster(db);

//获取Dao对象管理者

daoSession= daoMaster.newSession();

}

4:修改我们在build.gradle中数据库版本增加(只能加不能减)。

schemaVersion 7//指定数据库schema版本号,迁移等操作会用到

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • http://jinnianshilongnian.iteye.com/blog/2022468 Realm数据...
    天之大任阅读 259评论 0 0
  • 以前开发用到数据库时,基本上都是用android原生的sql语句,写那些语句时稍有不慎,就给你抛出一个except...
    BlainPeng阅读 7,643评论 2 12
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • 1. APP开发期间的数据库 在上一篇文章中封装了GreenDaoManager中有个构造方法如下: 其中注释掉的...
    闲庭阅读 4,597评论 6 11
  • 介绍 GreenDAO是一个对象关系映射(ORM)的框架,能够提供相关接口,通过操作对象的方式去操作关系型数据库。...
    flywfk阅读 1,355评论 0 1