之前使用的greendao数据库存储服务器所有的历史推送消息,但是后来消息需要加几个新的字段

举个栗子,比如要新增红色框住的字段到数据库中:

本仙女作为一只思想成熟的菜鸡,当然是加了字段就赶紧重新往里存,然后就一通报错android.database.sqlite.SQLiteException: no such column: T.XXX (code 1): , while compiling...

emm, 这种时候,求上进的仙女一般都会上网找问题

然后发现,原来是数据库没升级

嗯,

好的,

编不下去了

升级方法:

①.将新增的字段加入需要存储的bean类;

②.数据库版本号上升一个版本(我之前的version是1,升级改为2)

③.修改getDaoMaster()方法,原先是调用greendao里自动生成的

现在改成自己重写的helper类里的方法,是介锅样子的

相关代码了解一下

public class MigrationHelper {

    private static final String 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;
} public void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { generateTempTables(db, daoClasses);
DaoMaster.dropAllTables(db, true);
DaoMaster.createAllTables(db, false);
restoreData(db, daoClasses);
} /**
* 生成临时列表
*
* @param db
* @param daoClasses
*/
private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = ; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]); String divider = "";
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList<>(); StringBuilder createTableStringBuilder = new StringBuilder(); createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" ("); for (int j = ; 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 = new StringBuilder(); 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()); }
} /**
* 存储新的数据库表 以及数据
*
* @param db
* @param daoClasses
*/
private void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = ; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList(); for (int j = ; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName; if (getColumns(db, tempTableName).contains(columnName)) {
properties.add(columnName);
}
} StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(insertTableStringBuilder.toString());
db.execSQL(dropTableStringBuilder.toString());
}
} private String getTypeByClass(Class<?> type) throws Exception {
if (type.equals(String.class)) {
return "TEXT";
}
if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
return "INTEGER";
}
if (type.equals(Boolean.class)) {
return "BOOLEAN";
} Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
exception.printStackTrace();
throw exception;
} private List<String> getColumns(Database db, String tableName) {
List<String> 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();
}
return columns;
}
}

MigrationHelper

public class MyOpenHelper extends DaoMaster.OpenHelper {
public MyOpenHelper(Context context, String name) {
super(context, name);
} public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
} /**
* 数据库升级
*/
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
//操作数据库的更新 有几个表升级都可以传入到下面
MigrationHelper.getInstance().migrate(db, MyBeanDao.class);
}
}
public class DbManager {

    // 是否加密
public static final boolean ENCRYPTED = true; private static final String DB_NAME = "petssions.db";
private static DbManager mDbManager;
private static DaoMaster.DevOpenHelper mDevOpenHelper;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession; private Context mContext; public DbManager(Context context) {
this.mContext = context;
// 初始化数据库信息
mDevOpenHelper = new DaoMaster.DevOpenHelper(context, DB_NAME);
getDaoMaster(context);
getDaoSession(context);
} public static DbManager getInstance(Context context) {
if (null == mDbManager) {
synchronized (DbManager.class) {
if (null == mDbManager) {
mDbManager = new DbManager(context);
}
}
}
return mDbManager;
} /**
* 获取可读数据库
*
* @param context
* @return
*/
public static SQLiteDatabase getReadableDatabase(Context context) {
if (null == mDevOpenHelper) {
getInstance(context);
}
return mDevOpenHelper.getReadableDatabase();
} /**
* 获取可写数据库
*
* @param context
* @return
*/
public static SQLiteDatabase getWritableDatabase(Context context) {
if (null == mDevOpenHelper) {
getInstance(context);
}
return mDevOpenHelper.getWritableDatabase();
} /**
* 获取DaoMaster
*
* 判断是否存在数据库,如果没有则创建数据库
* @param context
* @return
*/
public static DaoMaster getDaoMaster(Context context) {
if (null == mDaoMaster) {
synchronized (DbManager.class) {
if (null == mDaoMaster) {
MyOpenHelper helper = new MyOpenHelper(context,DB_NAME,null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
}
}
}
return mDaoMaster;
} /**
* 获取DaoSession
*
* @param context
* @return
*/
public static DaoSession getDaoSession(Context context) {
if (null == mDaoSession) {
synchronized (DbManager.class) {
mDaoSession = getDaoMaster(context).newSession();
}
} return mDaoSession;
}

④.可以直接用DBManager里的方法获取dao类了,比如

DbManager.getDaoSession(getApplicationContext()).getBeanDao();
且原数据库中数据依旧保留。

详细代码取自 https://blog.csdn.net/huangxiaoguo1/article/details/54574713

记录一下寄几个儿的greendao数据库升级,可以说是非常菜鸡了嗯的更多相关文章

  1. GreenDao 数据库升级 连接多个DB文件 或者指定不同的model&dao目录

    相信很多人都用过greenDao 今天 我抽空总结下使用的时候一些小东西吧 废话不多说 下边就GreenDao 的使用遇到的问题以及解决方案记录一下吧. 1.greendao 指定不同的生成目录: S ...

  2. GreenDAO数据库版本升级

    GreenDAO是一款非要流行的android平台上的数据库框架,性能优秀,代码简洁. 初始化数据库模型代码的时候需要使用java项目生成代码,依赖的jar包已经上传到我的资源里了,下载地址如下:ht ...

  3. GreenDao 兼容升级,保留旧数据的---全方面解决方案

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  4. GreenDao 使用和数据库升级

    1使用方法 一.添加依赖 在bulid.gradle文件下的dependencies下添加所需依赖   compile 'org.greenrobot:greendao:3.2.2' // add l ...

  5. GreenDao数据库的升级

    应用使用了GreenDao数据库,在版本升级的时候需要更改dao的字段,新增.修改.删除字段操作,如果直接删除原来的表的话那用户原来的一些数据就没有了,所以在更新数据库的时候需要做一次封装,把原来的数 ...

  6. 生产环境中,数据库升级维护的最佳解决方案flyway

    官网:https://flywaydb.org/ 转载:http://casheen.iteye.com/blog/1749916 1.  引言 想到要管理数据库的版本,是在实际产品中遇到问题后想到的 ...

  7. Android 数据库升级解决方案

    转自:http://blog.csdn.net/leehong2005/article/details/9128501 请考虑如下情况: 在数据库升级时,不同版本的数据库,他们定义的表结构完全可能是不 ...

  8. Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())[4]

    数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0版本升级到1.1版 ...

  9. 探索Oracle数据库升级6 11.2.0.4.3 Upgrade12c(12.1.0.1)

    探索Oracle数据库升级6 11.2.0.4.3 Upgrade12c(12.1.0.1) 一.前言:       Oracle 12c公布距今已经一年有余了,其最大亮点是一个能够插拔的数据库(PD ...

随机推荐

  1. JS中parseint和number的区别

    两者定义的区别 parseInt将字符串(String)类型转为整数类型.Number() 函数把对象(Object)的值转换为数字. parseInt得到的结果是整数或者NaN,而Number得到的 ...

  2. CSS父元素高度随子元素高度变化而变化

    <html> <body> <head> <style> #menu{width:1000px;overfloat:hidden;} /* width: ...

  3. Oozie工作流属性配置的方式与策略

    本文原文出处: http://blog.csdn.net/bluishglc/article/details/46049817 Oozie工作流属性配置的三种方式 Oozie有三种方法可以给工作流提供 ...

  4. 牛腩学用MUI做手机APP

    斗鱼直播间直播学习撸码,最终目标是用MUI做一个手机APP(暂定android平台,攒钱买IPHONE 7SE!!!),直播内容含整个软件APP的制作过程(含后台接口的制作,放到自己买的阿里云服务器, ...

  5. 使用ASIHTTPRequest和ASIDownloadCache实现本地缓存

    源码:http://files.cnblogs.com/ios8/ASIHttpRequestDemo2.zip NSURL *url = [NSURLURLWithString:@"htt ...

  6. [svc]高并发场景 LVS DR +KeepAlive高可用实现及ka的persistence_timeout参数

    LVS-DR+keepalived模式是一种非常经典的常用生产组合 高可用场景及LVS架构 一般都用一(负载)拖多(Server Array)方式 使用LVS架设的服务器集群系统有三个部分组成: (1 ...

  7. Vuex 实践讲解

    state 用来数据共享数据存储 mutation 用来注册改变数据状态 getters 用来对共享数据进行过滤操作 action 解决异步改变共享数据 这个四大特征就是核心,如何用怎么用 接下来还是 ...

  8. FlexPaper:使用flash在线展示pdf

    WFTools工具包中的PDF2SWF工具可用来将PDF格式文件转换成SWF格式.使用下面的命令可以将pdf文件转换为单页swf文件. pdf2swf  pdfPath  –o swfPath  –T ...

  9. Bootstrap FileInput中文API整理

    这段时间做项目用到bootstrap fileinput插件上传文件,在用的过程中,网上能查到的api都不是很全,所以想着整理一份比较详细的文档,方便自己今后使用,也希望能给大家带来帮助,如有错误,希 ...

  10. 淘宝分布式数据层TDDL

    剖析淘宝 TDDL ( TAOBAO DISTRIBUTE DATA LAYER ) 注:原文:http://gao-xianglong.iteye.com/blog/1973591   前言 在开始 ...