GreenDao介紹
greenDAO是一個幫助Android開發(fā)者將數(shù)據(jù)存到SQLite中的一個開源項目祭衩。SQLite是一個很好的嵌入式關(guān)系數(shù)據(jù)庫。然而杂靶,開發(fā)它需要大量額外的工作碾盐。編寫SQL和解析查詢結(jié)果是相當(dāng)繁瑣的任務(wù)屎鳍。greenDAO將會為你做這些工作:它把Java對象映射到數(shù)據(jù)表(通常被叫做ORM:[https://en.wikipedia.org/wiki/Object-relational_mapping] )。這樣,你可以使用一個簡單的面向?qū)ο蟮慕涌趤泶鎯α凇⒏峦嵌簟h除和查詢Java對象。將時間集中在真正的問題上滞时。
greenDAO的主要設(shè)計目標(biāo)**
·性能最大化(對于Android來說叁幢,可能是最快的ORM)
·很容易使用APIs
·對Android高度優(yōu)化
·最小的內(nèi)存開銷
·較小的文件體積,將注意力集中在重點上
GreenDao項目引入
** gradle依賴 **
//greendao 3
compile 'org.greenrobot:greendao:3.2.2'
自定義數(shù)據(jù)庫升級邏輯
在gradle中添加greenDao version
greendao {
//數(shù)據(jù)庫版本號
schemaVersion 1
}
greenDao默認(rèn)的DevOpenHelper升級策略是丟棄所有數(shù)據(jù)坪稽,代碼如下:
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name) {
super(context, name);
}
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
}
自定義升級策略只需要自定義一個繼承OpenHelper的類曼玩,在onUpgrade方法中定義具體的升級邏輯。
然后在數(shù)據(jù)庫初始化的時候使用自定義的OpenHelper:
public static void init(WordApplication app) throws IOException{
WordDaoMaster.WordOpenHelper helper = new WordDaoMaster.WordOpenHelper(app,"dbname",null);
SQLiteDatabase db = helper.getWritableDatabase();
DBManager.daoMaster = new WordDaoMaster(db);
}
GreenDao使用中碰到的問題
greenDao的使用非常簡單窒百,但是使用中頁碰到了一些問題:
greenDao中沒有insertOrIgnore方法
開發(fā)中碰到一個需求黍判,需要批量插入數(shù)據(jù),如果數(shù)據(jù)庫中已經(jīng)存在這條數(shù)據(jù)篙梢,則忽略顷帖。
查了greendao的api,帶InTx后綴的方法在內(nèi)部已經(jīng)完成了事務(wù)的相關(guān)處理渤滞,例如如下代碼:
public static void addWordIntoWordMeaning(final List<WordMeaning> wordMeanings){
DaoSession daoSession = daoMaster.newSession();
WordMeaningDao wordMeaningDao = daoSession.getWordMeaningDao();
wordMeaningDao.insertOrReplaceInTx(wordMeanings);
}
使用起來的確非常簡單窟她,但是找了半天沒有insertOrIgnoreInTx的方法。其實蔼水,之前也有人提出了這個問題[https://github.com/greenrobot/greenDAO/pull/145]
但是greenDao的開發(fā)組沒有接受這個建議震糖,至今API里面沒有這個方法。如此一來趴腋,想要實現(xiàn)這個方法就必須自己改源碼了吊说。修改greenDao這種項目的源碼很容易自己改出bug。最后用如下方法解決:
DaoSession daoSession = daoMaster.newSession();
final ExamAnswerDao examAnswerDao = daoSession.getExamAnswerDao();
daoSession.runInTx(new Runnable() {
@Override
public void run() {
for(ExamAnswer examAnswer:list){
try {
examAnswerDao.insert(examAnswer);
}catch (Exception e){
Logcat.e(TAG,"record exist");
}
}
}
});
greenDao提供了一個runInTx的方法优炬,參數(shù)是一個Runnable實例颁井,對runnable內(nèi)的代碼使用事務(wù)操作。這里比較粗暴的用insert方法插入蠢护,對已經(jīng)存在的數(shù)據(jù)會報錯雅宾,直接catch住,這樣也能完成需求葵硕。