美文网首页andnroid
Android数据库升级,数据迁移。同时也适用GreenDao

Android数据库升级,数据迁移。同时也适用GreenDao

作者: 花蝶扇 | 来源:发表于2017-03-29 15:23 被阅读633次

    版本迭代时难免需要对数据库字段进行增加,删除与修改操作。这时便需要对原有的数据进行迁移,以保证不丢失数据。对数据库的迁移我们需要做一下几个步骤:

    • ① 创建临时表,将原来的数据复制到临时表中。
    • ② 删除原表,原表数据已经备份至临时表中,不再需要,进行删除。
    • ③ 创建新表,调用创建新表的方法,创建所有的新表。
    • ④ 恢复原表的数据,将临时表中的数据恢复至新表中。
    • ⑤ 删除临时表,完成所有的步骤。

    Show Code:

    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.text.TextUtils;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by CY on 2016/10/24.
     * Email: tmxdyf@163.com
     */
    
    public class UpgradeHelper {
    
    
        /**
         * 升级入口
         *
         * @param db db
         * @param openHelper 重新建表时需要用上
         */
        public void upgrade(SQLiteDatabase db, SQLiteOpenHelper openHelper) {
            List<String> tables = queryAllTables(db);
    
            for (String tableName : tables) {
                if ("android_metadata".equals(tableName)||"sqlite_sequence".equals(tableName)) {//表的元数据,过滤
                    continue;
                }
                String tempTableName = tableName + "_Temp";
                createTempTables(db, tableName, tempTableName);//创建临时表
                dropTable(db, tableName);//删除原表
                openHelper.onCreate(db);//创建新表
                restoreData(db, tableName, tempTableName);//恢复原表数据
                dropTable(db, tempTableName);//删除临时表
            }
        }
    
    
        /**
         * 创建零时表
         */
        private void createTempTables(SQLiteDatabase db, String tableName, String tempTableName) {
            copyTable(db, tableName, tempTableName);
        }
    
    
        /**
         * 删除所有表
         *
         * @param db
         */
        private void dropTable(SQLiteDatabase db, String tableName) {
    
            String sql = "DROP TABLE IF EXISTS " + tableName;
    
            db.execSQL(sql);
    
        }
    
    
        /**
         * 查询数据库中所有表名
         *
         * @param db
         * @return
         */
        private List<String> queryAllTables(SQLiteDatabase db) {
            List<String> list = new ArrayList<>();
            String sql = "SELECT name FROM SQLITE_MASTER WHERE type='table' ORDER BY name";
            Cursor cursor = db.rawQuery(sql, null);
            while (cursor.moveToNext()) {
                list.add(cursor.getString(0));
            }
            cursor.close();
            return list;
        }
    
    
        /**
         * 复制表及内容
         *
         * @param db
         * @param oldTableName
         * @param newTableName
         */
        private void copyTable(SQLiteDatabase db, String oldTableName, String newTableName) {
    
            String sql = "CREATE TABLE IF NOT EXISTS " + newTableName + " AS SELECT * FROM " + oldTableName;
            db.execSQL(sql);
        }
    
    
        /**
         * 从临时表中恢复数据
         *
         * @param db
         * @param tableName     需要恢复的表
         * @param tableNameTemp 临时表
         */
        private void restoreData(SQLiteDatabase db, String tableName, String tableNameTemp) {
    
    
            String columns = TextUtils.join(",", queryColumns(db, tableNameTemp));
    
            String sql = "INSERT INTO " + tableName + "(" + columns + ") SELECT " + columns + " FROM " + tableNameTemp;
    
            db.execSQL(sql);
    
        }
    
        /**
         * 获取表中所有字段名
         *
         * @return
         */
        private String[] queryColumns(SQLiteDatabase db, String tableName) {
    
            String sql = "SELECT * FROM " + tableName;
            Cursor cursor = db.rawQuery(sql, null);
            String[] columnNames = cursor.getColumnNames();
            cursor.close();
    
            return columnNames;
        }
    }
    
    

    如何使用?如以下示例。

    • E.g: GreenDao
      public class MergeDevOpenHelper extends DaoMaster.DevOpenHelper {
    
            public MergeDevOpenHelper(Context context, String name) {
                super(context, name);
            }
    
            public MergeDevOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
                super(context, name, factory);
            }
    
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                if (newVersion > oldVersion) {
                    new UpgradeHelper().upgrade(db, this);
                }
            }
    
        }
    
    
    }
    
     DaoMaster.DevOpenHelper devOpenHelper = new MergeDevOpenHelper(mContext, "data.db");
     SQLiteDatabase db = devOpenHelper.getWritableDatabase();
     DaoMaster daoMaster = new DaoMaster(db);
    

    这是我在简书的第一篇文章,希望能帮助到大家,同时也给我自己加深记忆。谢谢。_

    相关文章

      网友评论

        本文标题:Android数据库升级,数据迁移。同时也适用GreenDao

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