1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| public class MigrationHelper {
/** * 调用升级方法 * @param db * @param daoClasses 一系列dao.class */ public static void migrate(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) { //1 新建临时表 generateTempTables(db, daoClasses); //2 创建新表 createAllTables(db, false, daoClasses); //3 临时表数据写入新表,删除临时表 restoreData(db, daoClasses); }
/** * 生成临时表,存储旧的表数据 * @param db * @param daoClasses */ private static void generateTempTables(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) { //方法2 for (int i=0;i<daoClasses.length;i++){ DaoConfig daoConfig = new DaoConfig(db,daoClasses[i]); String tableName = daoConfig.tablename; if (!checkTable(db,tableName)) continue; String tempTableName = daoConfig.tablename.concat("_TEMP"); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("alter table ") .append(tableName) .append(" rename to ") .append(tempTableName) .append(";"); db.execSQL(insertTableStringBuilder.toString()); } }
/** * 检测table是否存在 * @param db * @param tableName */ private static Boolean checkTable(SQLiteDatabase db,String tableName){ StringBuilder query = new StringBuilder(); query.append("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='").append(tableName).append("'"); Cursor c = db.rawQuery(query.toString(), null); if (c.moveToNext()){ int count = c.getInt(0); if(count>0){ return true; } return false; } return false; }
/** * 删除所有旧表 * @param db * @param ifExists * @param daoClasses */ private static void dropAllTables(SQLiteDatabase db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "dropTable", ifExists, daoClasses); }
/** * 创建新的表结构 * @param db * @param ifNotExists * @param daoClasses */ private static void createAllTables(SQLiteDatabase db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "createTable", ifNotExists, daoClasses); }
/** * 创建根删除都在NoteDao声明了,可以直接拿过来用 * dao class already define the sql exec method, so just invoke it */ private static void reflectMethod(SQLiteDatabase db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { if (daoClasses.length < 1) { return; } try { for (Class cls : daoClasses) { //根据方法名,找到声明的方法 Method method = cls.getDeclaredMethod(methodName, SQLiteDatabase.class, boolean.class); method.invoke(null, db, isExists); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }
/** * 临时表的数据写入新表 * @param db * @param daoClasses */ private static void restoreData(SQLiteDatabase 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"); if (!checkTable(db,tempTableName)) continue; // get all columns from tempTable, take careful to use the columns list List<String> columns = getColumns(db, tempTableName); //新表,临时表都包含的字段 ArrayList<String> properties = new ArrayList<>(columns.size()); for (int j = 0; j < daoConfig.properties.length; j++) { String columnName = daoConfig.properties[j].columnName; if (columns.contains(columnName)) { properties.add(columnName); } } if (properties.size() > 0) { final String columnSQL = TextUtils.join(",", properties);
StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(") SELECT "); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); db.execSQL(insertTableStringBuilder.toString()); } StringBuilder dropTableStringBuilder = new StringBuilder(); dropTableStringBuilder.append("DROP TABLE ").append(tempTableName); db.execSQL(dropTableStringBuilder.toString()); } }
private static List<String> getColumns(SQLiteDatabase db, String tableName) { List<String> columns = null; Cursor cursor = null; try { cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null); if (null != cursor && cursor.getColumnCount() > 0) { columns = Arrays.asList(cursor.getColumnNames()); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); if (null == columns) columns = new ArrayList<>(); } return columns; } }
|