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<ReCreateAllTableListener> weakListener;

    public interface ReCreateAllTableListener{

        void onCreateAllTables(Database db, boolean ifNotExists);

        void onDropAllTables(Database db, boolean ifExists);

}

    public static void migrate(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... 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<? extends AbstractDao<?, ?>>... daoClasses) {

        weakListener = new WeakReference<>(listener);

        migrate(db, daoClasses);

}

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

        weakListener = new WeakReference<>(listener);

        migrate(database, daoClasses);

}

    public static void migrate(Database database, Class<? extends AbstractDao<?, ?>>... 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<? extends AbstractDao<?, ?>>... 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<? extends AbstractDao<?, ?>>... daoClasses) {

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

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

}

    private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... 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<? 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(Database 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 (!isTableExists(db, true, tempTableName)) {

                continue;

}

            try {

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

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

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

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

                ArrayList<String> 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<String> getColumns(Database 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;

}

    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<TableInfo> 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<TableInfo> 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)、把你原来已经安装好的程序卸载掉再进行测试。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容