Android-GreenDao增刪改查以及底層實現簡介
GreenDao 初始化:
public voidinitDB(Context context,String dbName)
{
this.context= context;
DaoMaster.DevOpenHelper helper =newDaoMaster.DevOpenHelper(context,"name_jia_"+ dbName, null);
instance.sqlDb= helper.getWritableDatabase();
instance.cx_jia_daoMaster=newDaoMaster(instance.sqlDb);
instance.cx_jia_daoSession=instance.cx_jia_daoMaster.newSession();
}
這個程式碼主要是用於建立資料庫和初始化一些變數,如初始化NoteDao的父類AbstractDao的變數和引數,
protected final SQLiteDatabase db;
protected final DaoConfig config;
protected IdentityScope identityScope;
protected IdentityScopeLong identityScopeLong;
protected TableStatements statements;
protected final AbstractDaoSession session;
protected final int pkOrdinal;
注意:
SQLiteDatabase db:我們建立的資料庫物件;
DaoConfig config:用於儲存資料訪問物件Dao的基本資料;
TableStatements statements:用於生成操作資料表的SQL statements;
identityScope:greendao有一個快取機制,即把使用者插入,更改或查詢的實體儲存在記憶體中,當用戶下一次查詢時先從記憶體中查詢
,如果不存在再從資料庫中查詢,當表的主鍵是數字型別的時候,identityScopeLong將不會空,並且指向identityScope。
在初始每個dao物件的DaoConfig的時候,判斷主鍵是否是數字型別,
主鍵初始化:
如果主鍵是數字型別的話,initIdentityScope時identityScope 初始化IdentityScopeLong型別,
然後在資料操作物件的父類(AbstractDao)的構造方法中,將identityScopeLong 指向identityScope,之後我們只需要extends就可以了,如下圖
然後,所有主鍵為數字型別dao物件獲取記憶體中快取物件的都會呼叫IdentityScopeLong中的get方法
所以,如果主鍵不是long型別的話就會報型別轉換錯誤!
我們可以自己控制是否使用快取功能,在DaoMaster中有兩個初始化DaoSession的方法,我們可以使用第二個構造方法並傳入type為IdentityScopeType.None,這樣initIdentityScope方法就會包identityScope 賦為空值,即不使用快取機制。
再次強調:在使用greendao快取機制的情況下,如果資料表的主鍵是數字型別的話,一定要使用long型別,不然不會報型別轉換錯誤。。大家可以去實踐下
好進入正題:
1)插入物件(insert):
User user= new User("id","name");
getUserDao().insert(user);
底層程式碼如下:
首先判斷資料庫是否被當前執行緒鎖住,如果是,繫結引數並執行插入,如果不是,則開啟一個事務,然後繫結引數並執行插入。
其中,UserDao重寫了父類AbstractDao的bindValues方法,進行相對應物件資料的繫結,
updateKeyAfterInsertAndAttach(entity, rowId, true)是為了更新自增主鍵的id,將實體放入快取中。
(當然還有insertOrReplace ,他們直接的區別大家自己動手去研究,可以說從字面上理解就好了。深層次上的理解就得從sql語句了)
2)刪除物件delete:
userDao.deleteByKey(id)
底層實現程式碼如下:
刪除物件與插入物件相似,刪除操作目前僅支援操作單一主鍵的表,assertSinglePk()是判斷物件是否是單一主鍵,若不是則丟擲錯誤。
往往我們要的是根據某個欄位進行刪除,如下
public void deleteMsgByUserName(String username) {
userDao.queryBuilder().where(UserDao.Properties.Username.eq(username)).buildDelete().executeDeleteWithoutDetachingEntities();
}
3)更改物件update:
userDao.update(user)
底層程式碼實現:
具體也是和新增,刪除一樣,先判斷執行緒,然後再判斷主鍵id。
當然我們也可以使用之前說的insertOrReplace,進行更新,底層程式碼和新增一樣,區別在
Stringsql = SqlUtils.createSqlInsert("INSERT OR REPLACE INTO ",tablename,allColumns);
SQLiteStatement newInsertOrReplaceStatement =db.compileStatement(sql);
在編譯時候到底是Inert 還是replace..
4)查詢
查詢物件的實現實現是原理是傳入多個限制條件,然後在底層程式碼中拼接sql查詢語句進行查詢,然後在轉換成相對應的物件。查詢的機制跟其他操作方式一樣,如果有使用greendao的快取機制,則先從快取中獲取,再從資料庫獲取,如果沒有使用快取機制,則直接從資料庫中獲取。
如果需要使用更復雜的查詢方法的話,可以檢視Property類和QueryBuilder的原始碼,greendao提供多種方式的拼接,可以組成日常開發中經常用到的查詢語句。
需要一提的是greendao的懶載入功能。這個以後再說。
文/kecai(簡書作者)
原文連結:http://www.jianshu.com/p/5681e183926d
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。