GreenDao3+ 升級

給數(shù)據(jù)庫添加一個字段:

通常只需要在對應(yīng)的表(實體類)中添加想要的字段 吩蔑,然后如圖操作!

即Rebuild Project 嚎莉,再將 schemaVersion 進(jìn)行修改即可即可铃将。
這種方式的問題會將歷史數(shù)據(jù)全部刪除名段,包括其他未修改的表炕舵,可能是重新創(chuàng)建新的數(shù)據(jù)庫吧拄查。除非不需要歷史數(shù)據(jù)豪娜,否則無法采用這種方式餐胀。

在使用Sqlite3的時候我們通常都是自定義 helper 類 通過 onCreate 方法初始化,通過 onUpgrade()方法 進(jìn)行更新的瘤载,同理 GreenDao這里也可以使用這個方法骂澄,但是沒辦法直接使用sql 語句alter去添加字段,可能是因為關(guān)系型數(shù)據(jù)庫的原因吧惕虑,具體沒深入了解坟冲,但是我們依然可以通過 onUpgrade()在生級的時候會被執(zhí)行的特點來進(jìn)行數(shù)據(jù)庫升級磨镶。

1.自定義 helper

public class DBHelper extends DaoMaster.OpenHelper {

    public DBHelper(Context context, String name) {

        super(context, name);

    }

    @Override

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

        super.onUpgrade(db, oldVersion, newVersion);//有人說要去掉這句,但是我沒發(fā)現(xiàn)有問題健提,如果有問題可以去掉試一試

        if(oldVersion<newVersion){

            MigrationHelper.getInstance().migrate(db,AnimalDao.class,PersonDao.class);//重點在這里 國外大神封裝的一個類琳猫,具體邏輯就是創(chuàng)建臨時庫記錄原始數(shù)據(jù),然后將數(shù)據(jù)copy 到新庫中
//[https://stackoverflow.com/questions/13373170/greendao-schema-update-and-data-migration/30334668#30334668](https://stackoverflow.com/questions/13373170/greendao-schema-update-and-data-migration/30334668#30334668)


        }

    }

}

MigrationHelper 類

package com.green.dao;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;

import com.greendao.gen.DaoMaster;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.internal.DaoConfig;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MigrationHelper {
    private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
    private static MigrationHelper instance;

    public static MigrationHelper getInstance() {
        if(instance == null) {
            instance = new MigrationHelper();
        }
        return instance;
    }

    public void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        generateTempTables(db, daoClasses);
        DaoMaster.dropAllTables(db, true);
        DaoMaster.createAllTables(db, false);
        restoreData(db, daoClasses);
    }

    private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        for(int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

            String divider = "";
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            ArrayList<String> properties = new ArrayList<>();

            StringBuilder createTableStringBuilder = new StringBuilder();

            createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");

            for(int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if(getColumns(db, tableName).contains(columnName)) {
                    properties.add(columnName);

                    String type = null;

                    try {
                        type = getTypeByClass(daoConfig.properties[j].type);
                    } catch (Exception exception) {
                    }

                    createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

                    if(daoConfig.properties[j].primaryKey) {
                        createTableStringBuilder.append(" PRIMARY KEY");
                    }

                    divider = ",";
                }
            }
            createTableStringBuilder.append(");");

            db.execSQL(createTableStringBuilder.toString());

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tableName).append(";");

            db.execSQL(insertTableStringBuilder.toString());
        }
    }

    private 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");
            ArrayList<String> properties = new ArrayList();

            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if(getColumns(db, tempTableName).contains(columnName)) {
                    properties.add(columnName);
                }
            }

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();

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

            db.execSQL(insertTableStringBuilder.toString());
            db.execSQL(dropTableStringBuilder.toString());
        }
    }

    private String getTypeByClass(Class<?> type) throws Exception {
        if(type.equals(String.class)) {
            return "TEXT";
        }
        if(type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
            return "INTEGER";
        }
        if(type.equals(Boolean.class)) {
            return "BOOLEAN";
        }

        Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
        throw exception;
    }

    private static List<String> getColumns(Database db, String tableName) {
        List<String> columns = new ArrayList<>();
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
            if (cursor != null) {
                columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
            }
        } catch (Exception e) {
            Log.v(tableName, e.getMessage(), e);
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return columns;
    }
}

創(chuàng)建數(shù)據(jù)庫改為:

DBHelper openHelper =new DBHelper(App.getInstance(),"test");//改為調(diào)用自定義的helper

  daoMaster =new DaoMaster(openHelper.getWritableDatabase());

daoSession =daoMaster.newSession();

如果是數(shù)據(jù)量比較大的時候這種方式應(yīng)該不是特別好吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末私痹,一起剝皮案震驚了整個濱河市脐嫂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌紊遵,老刑警劉巖账千,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異暗膜,居然都是意外死亡匀奏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門学搜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娃善,“玉大人,你說我怎么就攤上這事瑞佩【刍牵” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵炬丸,是天一觀的道長瘫寝。 經(jīng)常有香客問我,道長稠炬,這世上最難降的妖魔是什么焕阿? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮酸纲,結(jié)果婚禮上捣鲸,老公的妹妹穿的比我還像新娘瑟匆。我一直安慰自己闽坡,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布愁溜。 她就那樣靜靜地躺著疾嗅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冕象。 梳的紋絲不亂的頭發(fā)上代承,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音渐扮,去河邊找鬼论悴。 笑死掖棉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的膀估。 我是一名探鬼主播幔亥,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼察纯!你這毒婦竟也來了帕棉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤饼记,失蹤者是張志新(化名)和其女友劉穎香伴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體具则,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡即纲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乡洼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崇裁。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖束昵,靈堂內(nèi)的尸體忽然破棺而出拔稳,到底是詐尸還是另有隱情,我是刑警寧澤锹雏,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布巴比,位于F島的核電站,受9級特大地震影響礁遵,放射性物質(zhì)發(fā)生泄漏轻绞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一佣耐、第九天 我趴在偏房一處隱蔽的房頂上張望政勃。 院中可真熱鬧,春花似錦兼砖、人聲如沸奸远。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懒叛。三九已至,卻和暖如春耽梅,著一層夾襖步出監(jiān)牢的瞬間薛窥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工眼姐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诅迷,地道東北人佩番。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像罢杉,于是被迫代替她去往敵國和親答捕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354