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

GreenDao3,当我们进行数据库版本升级的时候,会默认删除删除所有的表,然后重新创建Android GreenDao3数据库升级,数据迁移_第1张图片
WARNING已经提示我们了,如果我们需求是在升级数据库之后保存当前的所有数据,则需要对onUpgrade( )方法重写。

/**
 * @作者:TJ
 * @时间:2018-11-01
 * @描述:数据库辅助类
 */
public class DBHelper extends DaoMaster.DevOpenHelper {
    public DBHelper(Context context) {
        super(context, Constants.DB_NAME, null);
    }
    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        //  2018-11-02  需要进行数据迁移更新的实体类 ,新增的不用加
        DBMigrationHelper.getInstance().migrate(db, ConsumeInfoDao.class, QuotaInfoDao.class);
    }
}

数据库初始化时调用,GreenDaoContext是自定义数据储存路径的类,详情参考GreenDao3自定义数据库路径SD卡

public void initDB(){
        DBHelper dbHelper = new DBHelper(new GreenDaoContext());
        mDatabase = dbHelper.getReadableDatabase();
        mDaoMaster = new DaoMaster(mDatabase);
        mDaoSession = mDaoMaster.newSession();
    }

DBMigrationHelper是为某大神写的,如下:

/**
 * @作者:TJ
 * @时间:2018-11-02
 * @描述:数据库迁移
 */
public class DBMigrationHelper {

    private static DBMigrationHelper instance;

    public static DBMigrationHelper getInstance() {
        if (instance == null) {
            instance = new DBMigrationHelper();
        }
        return instance;
    }

    /**
     * 获取列的名字
     *
     * @param db
     * @param tableName
     * @return
     */
    private static List getColumns(Database db, String tableName) {
        List 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.e(tableName, e.getMessage(), e);
            e.printStackTrace();
        }
        finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return columns;
    }


    /**
     * 数据库迁移
     *
     * @param db
     * @param daoClasses
     */
    public void migrate(Database db, Class... 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... 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     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());
            Log.e("DBMigrationHelper", "generateTempTables: sql:" + 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());
            Log.e("DBMigrationHelper", "generateTempTables: sql:" + insertTableStringBuilder.toString());
        }
    }

    /**
     * 恢复数据
     *
     * @param db
     * @param daoClasses
     */
    private void restoreData(Database db, Class... 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 properties      = new ArrayList();
            ArrayList propertiesQuery = 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);
                    propertiesQuery.add(columnName);
                } else {
                    try {
                        if (getTypeByClass(daoConfig.properties[j].type).equals("INTEGER")) {
                            propertiesQuery.add("0 as " + columnName);
                            properties.add(columnName);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            StringBuilder insertTableStringBuilder = new StringBuilder();
            insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", propertiesQuery));
            insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();
            dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);

            db.execSQL(insertTableStringBuilder.toString());
            db.execSQL(dropTableStringBuilder.toString());

            Log.e("DBMigrationHelper", "restoreData: sql:" + insertTableStringBuilder.toString());
            Log.e("DBMigrationHelper", "restoreData: sql:" + dropTableStringBuilder.toString());
        }
    }

    /**
     * @param type
     * @return
     * @throws Exception
     */
    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) || type.equals(int.class)) {
            return "INTEGER";
        }

        if (type.equals(Boolean.class) || type.equals(boolean.class)) {
            return "BOOLEAN";
        }

        Exception exception = new Exception("migration helper - class doesn't match with the 
        current parameters".concat(" - Class: ").concat(type.toString()));
        exception.printStackTrace();
        throw exception;
    }
}

你可能感兴趣的:(【Android工具】)