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对象来创建数据库:我们可以看到里面的源码:

GreenDao加密与更新升级_第1张图片
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版本号,迁移等操作会用到

你可能感兴趣的:(GreenDao加密与更新升级)