• GreenDao数据库的升级


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

    代码是用的网上的大神的,经过一些修改。利用这个类替换在Application里面的Helper类就可以完成数据的迁移了。

    import android.database.Cursor;
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.example.bob.testlistener.database.greendao.DaoMaster;
    
    import org.greenrobot.greendao.AbstractDao;
    import org.greenrobot.greendao.database.Database;
    import org.greenrobot.greendao.internal.DaoConfig;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    
    
    /**
     * Created by pokawa on 18/05/15.
     * 数据迁移类(数据库版本升级的时候使用这个类,会保留先前版本的数据)
     */
    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);
        }
    
        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) {
                            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());
            }
        }
    
        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(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()));
    //        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;
        }
    }

    这是在application里面的初始化GreenDao方法

      /**
         * 初始化GreenDao
         */
        private void initGreenDao() {
            MyGreenHelper helper = new MyGreenHelper(this,"test_user.db");
            SQLiteDatabase db = helper.getWritableDatabase();
            DaoMaster daoMaster = new DaoMaster(db);
            daoSession = daoMaster.newSession();
        }

    完成上面的修改后,就能够在entity里面更改数据库的字段了,然后make一下工程,生成新的daoMaster;

    最后在gradle文件里面更改数据库版本号

    greendao {
        schemaVersion 2 //数据库版本号
        daoPackage 'com.example.bob.testlistener.database.greendao'// 设置DaoMaster、DaoSession、Dao 包名
        targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录
    }

    数据库更新后原来的数据的新增或者更改字段的值都是null,需要在代码里面做相应的处理。

  • 相关阅读:
    数据库事务的四大特性以及事务的隔离级别
    数据库事务
    Java 反射机制(包括组成、结构、示例说明等内容)
    Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
    一分钟教你知道乐观锁和悲观锁的区别
    vue-router的history模式发布配置
    asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档
    ubuntu下查看-卸载软件(卸载.net core sdk的方法)
    ubuntu终端执行shell脚本报command not found解决方法
    sqlserver 重置标识列
  • 原文地址:https://www.cnblogs.com/BobAdmin/p/8930591.html
Copyright © 2020-2023  润新知