美文网首页
GreenDao数据库升级工具

GreenDao数据库升级工具

作者: 好学人 | 来源:发表于2019-07-07 13:53 被阅读0次

    MigrationHelper

    参考资料

    greendao-schema-update-and-data-migration

    使用方法

    // StandardDatabase can be found in greendao and this is the import
    import org.greenrobot.greendao.database.StandardDatabase;
    
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        MigrationHelper.migrate(new StandardDatabase(sqLiteDatabase),
                    UserDao.class,
                    ItemDao.class);
        // OR you can use it like this (Dont use both it is example of 2 different usages)
        MigrationHelper.migrate(sqLiteDatabase,
                    UserDao.class,
                    ItemDao.class);
    }
    

    源码如下

    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.support.annotation.NonNull;
    import android.text.TextUtils;
    
    import org.greenrobot.greendao.AbstractDao;
    import org.greenrobot.greendao.database.Database;
    import org.greenrobot.greendao.database.StandardDatabase;
    import org.greenrobot.greendao.internal.DaoConfig;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * Createdby PedroOkawa and modified by MBH on 16/08/16.
     */
    public final class MigrationHelper {
    
        public static void migrate(SQLiteDatabase sqliteDatabase, Class<? extends AbstractDao<?, ?>>... daoClasses) {
            StandardDatabase db = new StandardDatabase(sqliteDatabase);
            generateNewTablesIfNotExists(db, daoClasses);
            generateTempTables(db, daoClasses);
            dropAllTables(db, true, daoClasses);
            createAllTables(db, false, daoClasses);
            restoreData(db, daoClasses);
        }
    
        public static void migrate(StandardDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
            generateNewTablesIfNotExists(db, daoClasses);
            generateTempTables(db, daoClasses);
            dropAllTables(db, true, daoClasses);
            createAllTables(db, false, daoClasses);
            restoreData(db, daoClasses);
        }
    
        private static void generateNewTablesIfNotExists(StandardDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
            reflectMethod(db, "createTable", true, daoClasses);
        }
    
        private static void generateTempTables(StandardDatabase 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");
                StringBuilder insertTableStringBuilder = new StringBuilder();
                insertTableStringBuilder.append("CREATE TEMP TABLE ").append(tempTableName);
                insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";");
                db.execSQL(insertTableStringBuilder.toString());
            }
        }
    
        private static void dropAllTables(StandardDatabase db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
            reflectMethod(db, "dropTable", ifExists, daoClasses);
        }
    
        private static void createAllTables(StandardDatabase db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
            reflectMethod(db, "createTable", ifNotExists, daoClasses);
        }
    
        /**
         * dao class already define the sql exec method, so just invoke it
         */
        private static void reflectMethod(StandardDatabase 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, Database.class, boolean.class);
                    method.invoke(null, db, isExists);
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
        private static void restoreData(StandardDatabase 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");
                // 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(StandardDatabase 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;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:GreenDao数据库升级工具

          本文链接:https://www.haomeiwen.com/subject/eupbhctx.html