做者:林冠宏 / 指尖下的幽灵java
掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8android
博客:http://www.cnblogs.com/linguanh/git
GitHub : https://github.com/af913337456/github
腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activitiessql
开源地址:github.com/af913337456…数据库
使用 greenDao 做为线上APP 的本地 orm 框架时候,总有数据库表要更新的一天,或早或迟。框架
android.database.sqlite.SQLiteException
类异常。第一个状况会直接致使 APP 闪退掉,第二种就是数据不匹配。ide
先删除原来的表格,再建立新的
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
......
@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);
}
}
复制代码
xxxDao.java
类的,都会在每一次 build 的时候从新被生成,意味着我的的内嵌修改老是无效,由于老是覆盖你的。自定义升级策略。 思路参考ui
在上面的基础上作出以下步骤总结: (看不懂的看下面的符号描述
)this
对应上面的步骤描述:
基于上面的二次修改和拓展
GreenDaoCompatibleUpdateHelper.java
顾名思义,兼容旧表性质的 greenDao 数据库升级,不会形成旧表的数据丢失
MyGreenDaoDbHelper.java
自定义的 dbHelper,重载 onUpgrade
if (oldVersion < newVersion) {
Log.e("MyGreenDaoDbHelper","进行数据库升级");
new GreenDaoCompatibleUpdateHelper()
.setCallBack(
new GreenDaoCompatibleUpdateHelper.GreenDaoCompatibleUpdateCallBack() {
@Override
public void onFinalSuccess() {
Log.e("MyGreenDaoDbHelper","进行数据库升级 ===> 成功");
}
@Override
public void onFailedLog(String errorMsg) {
Log.e("MyGreenDaoDbHelper","升级失败日志 ===> "+errorMsg);
}
}
)
.compatibleUpdate(
db,
PostBeanDao.class,
MatterUserBeanDao.class,
PropsBeanDao.class,
ChannelChatsBeanDao.class,
JoinToChannelReqBeanDao.class
);
Log.e("MyGreenDaoDbHelper","进行数据库升级--完成");
}
复制代码
public final class GreenDaoCompatibleUpdateHelper {
public interface GreenDaoCompatibleUpdateCallBack{
void onFinalSuccess();
void onFailedLog(String errorMsg);
}
private static GreenDaoCompatibleUpdateCallBack callBack;
@SuppressWarnings("all")
public void compatibleUpdate(SQLiteDatabase sqliteDatabase, Class<? extends AbstractDao<?, ?>>... daoClasses) {
StandardDatabase db = new StandardDatabase(sqliteDatabase);
/** 建立以前旧表中不存在的新表 */
if(!generateNewTablesIfNotExists_withNoExchangeData(db, daoClasses))
return;
/** 建立中间表 & 把旧表的数据迁移到中间表 */
if(!generateTempTables_withExchangeDataFromOldTable(db, daoClasses))
return;
/** 把旧表所有删除 */
if(!dropAllTables(db, true, daoClasses))
return;
/** 建立全部新表 */
if(!createAllTables_withNoExchangeData(db, false, daoClasses))
return;
/** 把中间表的数据迁移到新表 & 删除中间表 */
restoreData_fromTempTableToNewTable(db, daoClasses);
if(callBack != null)
callBack.onFinalSuccess();
callBack = null;
}
public GreenDaoCompatibleUpdateHelper setCallBack(GreenDaoCompatibleUpdateCallBack callBack1){
callBack = callBack1;
return this;
}
...... // 去 gitHub 下载完整代码
}
复制代码
public class MyGreenDaoDbHelper extends DaoMaster.DevOpenHelper {
public MyGreenDaoDbHelper(Context context, String name) {
super(context, name);
}
public MyGreenDaoDbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
@SuppressWarnings("all")
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
Log.e("MyGreenDaoDbHelper", "----"+oldVersion + "---先前和更新以后的版本---" + newVersion+"----");
if (oldVersion < newVersion) {
Log.e("MyGreenDaoDbHelper","进行数据库升级");
new GreenDaoCompatibleUpdateHelper()
.setCallBack(
new GreenDaoCompatibleUpdateHelper.GreenDaoCompatibleUpdateCallBack() {
@Override
public void onFinalSuccess() {
Log.e("MyGreenDaoDbHelper","进行数据库升级 ===> 成功");
}
@Override
public void onFailedLog(String errorMsg) {
Log.e("MyGreenDaoDbHelper","升级失败日志 ===> "+errorMsg);
}
}
)
.compatibleUpdate(
db,
PostBeanDao.class,
MatterUserBeanDao.class,
PropsBeanDao.class,
ChannelChatsBeanDao.class,
JoinToChannelReqBeanDao.class
);
Log.e("MyGreenDaoDbHelper","进行数据库升级--完成");
}
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
// 不要调用父类的,它默认是先删除所有表再建立
// super.onUpgrade(db, oldVersion, newVersion);
}
}
复制代码
SQLiteConstraintException: NOT NULL constraint failed
错误,解决方法,采用 Integer Boolean 类型替换,这个你只能妥协,由于 greenDao 做者不屑于在你建表的时候提供默认值方法。详情能够去看看 issue1, 答: sqlLite 的源码里面调用 onUpdrade
方法的入口皆加上了同步琐
,这样不会形成在升级中还能让你去读写的状况。 这点设计得很是优秀!表太多的,几百张?那么就放入子线程升级。
2, 答: 我已经使用到线上多个APP , 且成功运行至今。