Android GreenDao3資料庫升級,資料遷移
阿新 • • 發佈:2018-12-19
GreenDao3,當我們進行資料庫版本升級的時候,會預設刪除刪除所有的表,然後重新建立 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); } }
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<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.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; } }