之前使用的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. Android基础知识之String类使用详解

    原文:http://android.eoe.cn/topic/android_sdk 字符串资源为你的应用程序提供了可以选择的文本样式和格式的文本.这里有三种类型的资源可以为你的应用程序提供字符串. ...

  2. react-navigation使用技巧

      因为react-navigation之前存在的问题相对较多,本文更新会稍慢,而且,我现在项目使用的是基于它封装的react-native-router-fluxV4版本,现在也推荐给大家使用.在下 ...

  3. SQLMap 学习

    注入完整流程:http://mp.weixin.qq.com/s/G_DUUVuPH9DeWagjELCPfA sqlmap命令:http://www.cnblogs.com/handt/p/855f ...

  4. HTML5学习笔记(十):CSS常用操作

    对齐 在 CSS 中,可以使用多种属性来水平对齐元素. 水平对齐 使用 margin 属性来水平对齐,可通过将左和右外边距设置为 "auto",来对齐块元素. 把左和右外边距设置为 ...

  5. javascript基础拾遗(十二)

    1.javascript的单线程特性 在javascript中,所有的代码都是单线程的 因此所有的网络操作,浏览器事件,都必须是异步执行的,异步执行的逻辑是回调. function callback( ...

  6. javascript基础拾遗(二)

    1.对象定义 定义属性 var language = { name:'javascript', score:9.0 }; console.log(language.name) console.log( ...

  7. 关于go1.6使用vendor的坑

    基本命令是:$ govendor init$ govendor add +external 坑:如果在govendor之前,修改过go get的包源代码,那么必须在该包目录里git commit这个修 ...

  8. 非网络引用element-ui css导致图标无法正常显示的解决办法

    https://blog.csdn.net/m0_37893932/article/details/79460652 ***************************************** ...

  9. java多线程15 :wait()和notify() 的生产者/消费者模式

    什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...

  10. 检查jdk版本

    ### 检查JDK版本信息-----------------------------查看jdk是否已安装 javac查看jdk版本信息 javac -version查看jdk安装位置 java -ve ...