GreenDao3.0数据库升级,很简单,保存原有数据

不讲GreenDao是什么和怎么用,只讲升级,很简单,按照步骤来就行

一、新建一个类,

public class DBopenHelper extends DaoMaster.DevOpenHelper {

//  name  数据库名字

    public DBopenHelper(Context context, String name) {

        super(context, name);

}

    public DBopenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {

        super(context, name, factory);

}

    @Override

    public void onUpgrade(Database db, int oldVersion, int newVersion) {

        //把需要管理的数据库表DAO作为最后一个参数传入到方法中(只传更改过的表,新增的不用)

        MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {

            @Override

            public void onCreateAllTables(Database db, boolean ifNotExists) {

                DaoMaster.createAllTables(db, ifNotExists);

}

            @Override

            public void onDropAllTables(Database db, boolean ifExists) {

                DaoMaster.dropAllTables(db, ifExists);

}

        },  HangUpDao.class);//可添加多个改动过的表对象Dao

    }

}


注意:  HangUpDao.class);//可添加多个改动过的表对象Dao,这里就是你需要修改的表

二、再新建一个类

/*

* 数据库升级帮助类

* **/

public class MigrationHelper {

    public static boolean DEBUG = false;

    private static String TAG = "MigrationHelper";

    private static final String SQLITE_MASTER = "sqlite_master";

    private static final String SQLITE_TEMP_MASTER = "sqlite_temp_master";

    private static WeakReference weakListener;

    public interface ReCreateAllTableListener{

        void onCreateAllTables(Database db, boolean ifNotExists);

        void onDropAllTables(Database db, boolean ifExists);

}

    public static void migrate(SQLiteDatabase db, Class>... daoClasses) {

        printLog("【The Old Database Version】" + db.getVersion());

        Database database= new StandardDatabase(db);

        migrate(database, daoClasses);

}

    public static void migrate(SQLiteDatabase db, ReCreateAllTableListener listener, Class>... daoClasses) {

        weakListener = new WeakReference<>(listener);

        migrate(db, daoClasses);

}

    public static void migrate(Database database, ReCreateAllTableListener listener, Class>... daoClasses) {

        weakListener = new WeakReference<>(listener);

        migrate(database, daoClasses);

}

    public static void migrate(Database database, Class>... daoClasses) {

        printLog("【Generate temp table】start");

        generateTempTables(database, daoClasses);

        printLog("【Generate temp table】complete");

        ReCreateAllTableListener listener= null;

        if (weakListener != null) {

            listener= weakListener.get();

}

        if (listener!= null) {

            listener.onDropAllTables(database, true);

            printLog("【Drop all table by listener】");

            listener.onCreateAllTables(database, false);

            printLog("【Create all table by listener】");

        } else {

            dropAllTables(database, true, daoClasses);

            createAllTables(database, false, daoClasses);

}

        printLog("【Restore data】start");

        restoreData(database, daoClasses);

        printLog("【Restore data】complete");

}

    private static void generateTempTables(Database db, Class>... daoClasses) {

        for (int i= 0; i< daoClasses.length; i++) {

            String tempTableName= null;

            DaoConfig daoConfig= new DaoConfig(db, daoClasses[i]);

            String tableName= daoConfig.tablename;

            if (!isTableExists(db, false, tableName)) {

                printLog("【New Table】" + tableName);

                continue;

}

            try {

                tempTableName= daoConfig.tablename.concat("_TEMP");

                StringBuilder dropTableStringBuilder= new StringBuilder();

                dropTableStringBuilder.append("DROP TABLE IF EXISTS ").append(tempTableName).append(";");

                db.execSQL(dropTableStringBuilder.toString());

                StringBuilder insertTableStringBuilder= new StringBuilder();

                insertTableStringBuilder.append("CREATE TEMPORARY TABLE ").append(tempTableName);

                insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";");

                db.execSQL(insertTableStringBuilder.toString());

                printLog("【Table】" + tableName+"\n ---Columns-->"+getColumnsStr(daoConfig));

                printLog("【Generate temp table】" + tempTableName);

            } catch (SQLException e) {

                Log.e(TAG, "【Failed to generate temp table】" + tempTableName, e);

}

}

}

    private static boolean isTableExists(Database db, boolean isTemp, String tableName) {

        if (db== null || TextUtils.isEmpty(tableName)) {

            return false;

}

        String dbName= isTemp? SQLITE_TEMP_MASTER : SQLITE_MASTER;

        String sql= "SELECT COUNT(*) FROM " + dbName+ " WHERE type = ? AND name = ?";

        Cursor cursor=null;

        int count= 0;

        try {

            cursor= db.rawQuery(sql, new String[]{"table", tableName});

            if (cursor== null || !cursor.moveToFirst()) {

                return false;

}

            count= cursor.getInt(0);

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            if (cursor!= null)

                cursor.close();

}

        return count> 0;

}

    private static String getColumnsStr(DaoConfig daoConfig) {

        if (daoConfig== null) {

            return "no columns";

}

        StringBuilder builder= new StringBuilder();

        for (int i= 0; i< daoConfig.allColumns.length; i++) {

            builder.append(daoConfig.allColumns[i]);

            builder.append(",");

}

        if (builder.length() > 0) {

            builder.deleteCharAt(builder.length() - 1);

}

        return builder.toString();

}

    private static void dropAllTables(Database db, boolean ifExists, @NonNull Class>... daoClasses) {

        reflectMethod(db, "dropTable", ifExists, daoClasses);

        printLog("【Drop all table by reflect】");

}

    private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class>... daoClasses) {

        reflectMethod(db, "createTable", ifNotExists, daoClasses);

        printLog("【Create all table by reflect】");

}

    /**

* dao class already define the sql exec method, so just invoke it

*/

    private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class>... 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(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");

            if (!isTableExists(db, true, tempTableName)) {

                continue;

}

            try {

                // get all columns from tempTable, take careful to use the columns list

                List newTableInfos= TableInfo.getTableInfo(db, tableName);

                List tempTableInfos= TableInfo.getTableInfo(db, tempTableName);

                ArrayList selectColumns= new ArrayList<>(newTableInfos.size());

                ArrayList intoColumns= new ArrayList<>(newTableInfos.size());

                for (TableInfo tableInfo: tempTableInfos) {

                    if (newTableInfos.contains(tableInfo)) {

                        String column= '`' + tableInfo.name + '`';

                        intoColumns.add(column);

                        selectColumns.add(column);

}

}

                // NOT NULL columns list

                for (TableInfo tableInfo: newTableInfos) {

                    if (tableInfo.notnull && !tempTableInfos.contains(tableInfo)) {

                        String column= '`' + tableInfo.name + '`';

                        intoColumns.add(column);

                        String value;

                        if (tableInfo.dfltValue != null) {

                            value= "'" + tableInfo.dfltValue + "' AS ";

                        } else {

                            value= "'' AS ";

}

                        selectColumns.add(value+ column);

}

}

                if (intoColumns.size() != 0) {

                    StringBuilder insertTableStringBuilder= new StringBuilder();

                    insertTableStringBuilder.append("REPLACE INTO ").append(tableName).append(" (");

                    insertTableStringBuilder.append(TextUtils.join(",", intoColumns));

                    insertTableStringBuilder.append(") SELECT ");

                    insertTableStringBuilder.append(TextUtils.join(",", selectColumns));

                    insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

                    db.execSQL(insertTableStringBuilder.toString());

                    printLog("【Restore data】 to " + tableName);

}

                StringBuilder dropTableStringBuilder= new StringBuilder();

                dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);

                db.execSQL(dropTableStringBuilder.toString());

                printLog("【Drop temp table】" + tempTableName);

            } catch (SQLException e) {

                Log.e(TAG, "【Failed to restore data from temp table 】" + tempTableName, e);

}

}

}

    private static List getColumns(Database db, String tableName) {

        List 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;

}

    private static void printLog(String info){

        if(DEBUG){

            Log.d(TAG, info);

}

}

    private static class TableInfo {

        int cid;

        String name;

        String type;

        boolean notnull;

        String dfltValue;

        boolean pk;

        @Override

        public boolean equals(Object o) {

            return this == o

|| o!= null

                    && getClass() == o.getClass()

                    && name.equals(((TableInfo) o).name);

}

        @Override

        public String toString() {

            return "TableInfo{" +

                    "cid=" + cid +

                    ", name='" + name + '\'' +

                    ", type='" + type + '\'' +

                    ", notnull=" + notnull +

                    ", dfltValue='" + dfltValue + '\'' +

                    ", pk=" + pk +

                    '}';

}

        private static List getTableInfo(Database db, String tableName) {

            String sql= "PRAGMA table_info(" + tableName+ ")";

            printLog(sql);

            Cursor cursor= db.rawQuery(sql, null);

            if (cursor== null)

                return new ArrayList<>();

            TableInfo tableInfo;

            List tableInfos= new ArrayList<>();

            while (cursor.moveToNext()) {

                tableInfo= new TableInfo();

                tableInfo.cid = cursor.getInt(0);

                tableInfo.name = cursor.getString(1);

                tableInfo.type = cursor.getString(2);

                tableInfo.notnull = cursor.getInt(3) == 1;

                tableInfo.dfltValue = cursor.getString(4);

                tableInfo.pk = cursor.getInt(5) == 1;

                tableInfos.add(tableInfo);

                // printLog(tableName + ":" + tableInfo);

            }

            cursor.close();

            return tableInfos;

}

}

}

三、在 DaoManager 类里面,修改代码,关键

    /**

* 判断是否有存在数据库,如果没有则创建

*/

    public DaoMaster getDaoMaster() {

        if (mDaoMaster == null) {

//            mHelper = new DaoMaster.DevOpenHelper(mContext, DB_NAME, null);(原有代码)

            mHelper = new DBopenHelper(mContext, DB_NAME);//指向你新建的自定义的类

            mDaoMaster = new DaoMaster(mHelper.getWritableDatabase());

}

        return mDaoMaster;

    }

四、(1)、在你需要升级修改的数据库实体类里面,新增或者删除或者咋地都行,操作做完后,删除原有的 get set 方法,重新 build 一下,懂我意思吧,

        (2)、修改数据库版本号,+1 即可,不知道在哪修改先去学习 GreenDao如何配置,再来学升级。

        (3)、把你原来已经安装好的程序卸载掉再进行测试。

你可能感兴趣的:(GreenDao3.0数据库升级,很简单,保存原有数据)