参考:https://stackoverflow.com/questions/13373170/greendao-schema-update-and-data-migration/30334668#30334668

GreenDao升级时,默认删除所有数据
看源码可以发现原因:

public class DaoMaster extends AbstractDaoMaster {......public static class DevOpenHelper extends OpenHelper {public DevOpenHelper(Context context, String name) {super(context, name);}public DevOpenHelper(Context context, String name, CursorFactory factory) {super(context, name, factory);}@Overridepublic 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);}}}

想要保留数据,就要对 DevOpenHelper 进行修改,数据迁移思路先说明下。

第一步:先创建临时表,把老数据存入

第二步:把旧的表删除,新建数据库表

第三步:把临时表数据 ,存入新数据库

具体实现请看 MigrationHelper :

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;}/*** 迁移数据库* @param db* @param daoClasses*/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 = 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<String> properties = new ArrayList<>();StringBuilder createTableStringBuilder = new StringBuilder();createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");for(int j = 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) {
//                        Crashlytics.logException(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 = 0; 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 = 0; 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(Date.class) || type.equals(long.class) || type.equals(int.class) ) {return "INTEGER";}if(type.equals(Boolean.class)) {return "BOOLEAN";}Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
//        Crashlytics.logException(exception);throw exception;}private static 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;}
}

怎么使用这个工具类呢,需要继承DaoMaster.DevOpenHelper,重写onUpgrade方法

public class GmTechOpenHelper extends DaoMaster.DevOpenHelper {public GmTechOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {super(context, name, factory);}public GmTechOpenHelper(Context context, String name) {super(context, name);}@Overridepublic void onUpgrade(Database db, int oldVersion, int newVersion) {if (oldVersion < newVersion){MigrationHelper.getInstance().migrate(db, TestDao.class);}Log.d("GmTechOpenHelper", "oldVersion: "+oldVersion+",newVersion: "+newVersion);}
}

需要在greenDao初始化时,替换自定义的DaoMaster.DevOpenHelper

        //创建数据库mydb.dbDaoMaster.DevOpenHelper helper = new GmTechOpenHelper(BaseApplication.getContext(),"数据库名");//获取可写数据库SQLiteDatabase database = helper.getWritableDatabase();//获取数据库对象DaoMaster daoMaster = new DaoMaster(database);//获取Dao对象管理者daoSession = daoMaster.newSession();

GreenDao3.2 版本升级数据迁移相关推荐

  1. redis 版本升级及数据迁移

    https://github.com/redis/redis/security/advisories/GHSA-3qpw-7686-5984 Redis版本升级的新功能优化 - 米扑博客 redis ...

  2. Android GreenDao3数据库升级,数据迁移

    GreenDao3,当我们进行数据库版本升级的时候,会默认删除删除所有的表,然后重新创建 WARNING已经提示我们了,如果我们需求是在升级数据库之后保存当前的所有数据,则需要对onUpgrade( ...

  3. Grafana的版本升级和数据迁移

    [前言]Grafana是用于可视化大型测量数据的开源程序.界面比kibana更加美观,适合在电视和LED大屏幕展示!并且在结果分析可视化上,除了使用自带Dashboard外,还支持DataV.Graf ...

  4. hbase集群 数据写入_HBase神器 | BDSHBase集群之间数据迁移同步的利器

    BDS定位 BDS针对开源HBase目前存在的同步迁移痛点,自主研发的一套数据迁移的平台,用于HBase集群的无缝迁移.主备容灾.异地多活.在线离线业务分离.HBase数据归档.对接RDS实时增量数据 ...

  5. Atlassian data migrate 数据迁移

    Atlassian data migrate 数据迁移 数据迁移 在 Atlassian 的用户来看,都是让人觉得充满风险及工程艰巨的任务,但其实这个工作,在运维期间的各种场景会发现,数据迁移其实是一 ...

  6. 在Linux中进行禅道数据迁移

    原禅道数据在公网IP为x.x.x.x的服务器上的centos7系统中:禅道数据迁移到的新服务器是公网IP为y.y.y.y的服务器. 若新服务器上安装centos7系统,则有两种情况:一种是两台服务器用 ...

  7. 云时代,好用的数据迁移方案推荐

    数据库作为企业核心的数据存储引擎,在其提供服务的过程中,经常会因为各种各样的原因需要进行数据的迁移.数据库迁移作为一个古老的话题并不神秘,但因为迁移数据的重要性,以及业务对数据库可用性的高要求,导致数 ...

  8. iOS Core Data 数据迁移 指南 144 作者 一缕殇流化隐半边冰霜 关注 2016.05.09 00:35* 字数 4718 阅读 2931评论 17喜欢 327 前言 Core

    iOS Core Data 数据迁移 指南 作者 一缕殇流化隐半边冰霜 关注 2016.05.09 00:35* 字数 4718 阅读 2931评论 17喜欢 327 前言 Core Data是iOS ...

  9. Python + Mysql数据迁移

    导言:数据迁移对于软件开发过程中是必不可少的,有些公司会有专门的DBA,那数据迁移就归DBA搞定就好了,但大部分的公司不会单独去设立DBA这个职位,面对版本升级,数据库有所大改动的时候,测试人员可以利 ...

最新文章

  1. 在VMware Workstation上安装Kali Linux
  2. Cmder命令行工具在Windows系统中的配置
  3. 如何利用阿里云安全产品加强你的网站防护能力
  4. 【STM32】中断相关函数和类型
  5. 响应式系统reactive system初探
  6. 【报告分享】全球产业趋势系列研究之人工智能.pdf(附下载链接)
  7. inDesign教程,如何将内容与参考线对齐?
  8. Data crossstore between Mongo and JPA
  9. php+foreach+传值传值,php foreach 传值还是传引用
  10. GBin1分享:一个漂亮的jQuery页面内容导航插件 - Flexiable Nav
  11. 怎样编辑pdf文件?手把手教你如何使用PDF编辑器
  12. 操作系统中的基础抽象
  13. openAL在C++下的易用封装,调用直接播放3D音频,模拟3D音效
  14. 我最喜欢的10个顶级数据科学资源,kaggle、TDS、arXiv......
  15. 主流的巡店系统有哪些?哪个品牌比较好
  16. ORACLE MERGE INTO语句,unable to get a stable set of rows in the source tables报错解决
  17. 使用Puppeteer轻松爬取网易云音乐、QQ音乐的精品歌单
  18. Java并发编程:park线程
  19. 天翼文化参展深圳文博会 冒险大作《海盗鬼皮书》引热捧
  20. USB Mass Storage 6.7 The Thirteen Cases章节的理解

热门文章

  1. Mysql存储过程实践
  2. 《OpenCv视觉之眼》Python图像处理十 :Opencv图像形态学处理之开运算、闭运算和梯度运算原理及方法
  3. 03-学习笔记(HTML创建表格并通过for循环将数组内数据插入表格-vue)【新手上路,多多关照】
  4. 原华润微常务副董事长陈南翔,正式加盟紫光集团任联席总裁
  5. 练习:柱状图中最大矩形
  6. linux配置raid50怎么配置,=====创建Raid50的步骤======
  7. SQL(一) 数据库 去除重复值 select distinct
  8. PostgreSQL with(with recursive )查询
  9. PCB新手常用的几款软件?
  10. Spring与Mybatis整合