GreenDao3.0 源碼分析-DaoMaster和DaoSeesion

GreenDao3.0系列文章:

GreenDao3.0源碼分析-Helper

GreenDao3.0 源碼分析-DaoMaster和DaoSeesion

GreenDao3.0 源碼分析-Dao層

AbstractDaoMaster

image

從圖中我們知道,DaoMaster和AbstractDaoMaster是父子類的關(guān)系,我們先看AbstractDaoMaster:

image

從上面類圖中,我們知道daoMaster維護(hù)一個(gè)daoConfigMap以Dao.class為key維護(hù)一個(gè)映射關(guān)系,而且通過(guò)調(diào)用

image

我們可以知道 AbstractDaoMaster的功能主要職責(zé)之一是創(chuàng)建注冊(cè)DaoConfig,并且維護(hù)他和dao之間的關(guān)系。

實(shí)現(xiàn)類DaoMaster的功能

功能一:創(chuàng)建所有表和刪除所有表

image

通過(guò)調(diào)用XXXDAO的靜態(tài)方法來(lái)進(jìn)行建表和刪表。

功能二:創(chuàng)建Session會(huì)話

public DaoSession newSession() {
    return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}

public DaoSession newSession(IdentityScopeType type) {
    return new DaoSession(db, type, daoConfigMap);
}

兩個(gè)創(chuàng)建的默認(rèn)數(shù)據(jù)緩存的類型,一個(gè)是隨我們定義的類型,IdentityScopeType定義了兩個(gè)類型,后面再說(shuō)。

功能三:注冊(cè)Config:

 public DaoMaster(Database db) {
        super(db, SCHEMA_VERSION);
      registerDaoClass(NoteDao.class);
}

創(chuàng)建DaoMaster對(duì)象的時(shí)候以 Class<?> 來(lái)作為key,對(duì)DaoConfig進(jìn)行配置緩存綁定。

功能四:定義內(nèi)部類OpenHelper和DevOpenHelper。

Dao配置類DaoConfig

源碼對(duì)DaoConfig是這樣評(píng)價(jià)的:在GreenDao內(nèi)部使用,通過(guò)AbstractDaoMaster創(chuàng)建和持有其對(duì)象,存儲(chǔ)一些DAO實(shí)體所必須的數(shù)據(jù)。這個(gè)類實(shí)例能通過(guò)以Dao class為Key ,使用map維護(hù),通過(guò)key取出必要的信息。

也就是說(shuō),DaoConfig就是用來(lái)存儲(chǔ)dao,必要的一些數(shù)據(jù)的。

DaoConfig,維護(hù)了以下的字段:

image

上圖源碼可知,DaoConfig 維護(hù)了數(shù)據(jù)庫(kù)對(duì)象、數(shù)據(jù)庫(kù)名稱、Dao實(shí)體類表所有的屬性對(duì)應(yīng)關(guān)系等,并且這些字段都是在這個(gè)類進(jìn)行初始化的,核心功能有兩個(gè)。

根據(jù)xxxDao.class反射獲得屬性對(duì)象:

private static Property[] reflectProperties(Class<? extends AbstractDao<?, ?>> daoClass)
        throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException {
    Class<?> propertiesClass = Class.forName(daoClass.getName() + "$Properties");
    Field[] fields = propertiesClass.getDeclaredFields();

    ArrayList<Property> propertyList = new ArrayList<Property>();
    //根據(jù)反射的字段 拿出靜態(tài)和公開(kāi)的屬性對(duì)象
    final int modifierMask = Modifier.STATIC | Modifier.PUBLIC;
    for (Field field : fields) {
        //有些工具可能會(huì)引入其他字段,可以忽略它們
        if ((field.getModifiers() & modifierMask) == modifierMask) {
            Object fieldValue = field.get(null);
            if (fieldValue instanceof Property) {
                propertyList.add((Property) fieldValue);
            }
        }
    }
    //列表轉(zhuǎn)成數(shù)組,并通過(guò)序號(hào)進(jìn)行排序
    Property[] properties = new Property[propertyList.size()];
    for (Property property : propertyList) {
        if (properties[property.ordinal] != null) {
            throw new DaoException("Duplicate property ordinals");
        }
        properties[property.ordinal] = property;
    }
    return properties;
}</pre>

初始化緩存的策略

public enum IdentityScopeType {
        Session, None
}

數(shù)據(jù)庫(kù)緩存的種類有兩種。Session,就是使用內(nèi)存緩存,None就是不使用內(nèi)存緩存。

public void initIdentityScope(IdentityScopeType type) {
    if (type == IdentityScopeType.None) {
        identityScope = null;
    } else if (type == IdentityScopeType.Session) {
        if (keyIsNumeric) {
            identityScope = new IdentityScopeLong();
        } else {
            identityScope = new IdentityScopeObject();
        }
    } else {
        throw new IllegalArgumentException("Unsupported type: " + type);
    }
}

可以看到,當(dāng)我們創(chuàng)建Dao之前會(huì)調(diào)用這個(gè)方法,就說(shuō)明,如果type==IdentityScopeType.None沒(méi)有內(nèi)存緩存,反之會(huì)根據(jù)主鍵的類型,賦予內(nèi)存緩存的管理對(duì)象。

還有其他功能就是對(duì)TableStatements初始化,判斷主鍵是否是數(shù)字類型,分揀主鍵的數(shù)據(jù)和非主鍵的數(shù)組,記錄所有屬性行等大家可以看源碼,都比較簡(jiǎn)單。

Property、TableStatements是兩個(gè)非常重要的對(duì)象,留待后面我們?cè)僦v。

AbstractDaoSession

AbstractDaoSession維護(hù)是的Dao.calss對(duì)應(yīng)AbstractDao的關(guān)系,AbstractDao是所有實(shí)體Dao對(duì)象的父類,AbstractDaoSession里面就是實(shí)現(xiàn)一個(gè)從映射表中取出AbstractDao對(duì)象來(lái)進(jìn)行增刪改查的操作,也提供了runInTx(Runnable runnable)在事務(wù)中做任務(wù)不需要返回結(jié)果,和callInTx(Callable<V> callable)在事務(wù)中做任務(wù)并且等待結(jié)果等一些方法。

注:一些關(guān)于Rx和異步的操作留待后面統(tǒng)一再說(shuō)。

DaoSession

DaoSession是一個(gè)Dao會(huì)話,首先我們看構(gòu)造方法中的初始化

  public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
        daoConfigMap) {
    super(db);

    //根據(jù)Class<?>取出配置信息
    noteDaoConfig = daoConfigMap.get(NoteDao.class).clone();
    //根據(jù)Session的緩存類型初始化定制的緩存范圍
    noteDaoConfig.initIdentityScope(type);
    //根據(jù)配置初始化得到一個(gè)NoteDao實(shí)體
    noteDao = new NoteDao(noteDaoConfig, this);
    //注冊(cè)到映射表中
    registerDao(Note.class, noteDao);
}

由注釋可知,DaoSession會(huì)創(chuàng)建我們需要的Dao對(duì)象并注冊(cè)到映射表中管理起來(lái)。

每個(gè)Dao還會(huì)生成這樣的格式的語(yǔ)句,所以我們可以根據(jù)Session對(duì)象直接獲取到XXDao:

public XXDao getxxDao() {
    return xxDao;
}

還有一個(gè)清除所有內(nèi)存緩存的方法:

public void clear() {
    noteDaoConfig.clearIdentityScope();
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • (一)GreenDao簡(jiǎn)介 GreenDao是一個(gè)對(duì)象關(guān)系映射(ORM)的開(kāi)源框架,目前最主流的安卓數(shù)據(jù)庫(kù)操作框架...
    miss2008閱讀 5,548評(píng)論 4 18
  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后,其對(duì)應(yīng)的棧就會(huì)被回收,此時(shí),在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,570評(píng)論 1 14
  • 將項(xiàng)目從greenDAO從2.x版本升級(jí)到最新的3.2版本,最大變化是可以用注解代替以前的java生成器。實(shí)現(xiàn)這點(diǎn)...
    展翅而飛閱讀 9,113評(píng)論 6 21
  • 這部分主要是開(kāi)源Java EE框架方面的內(nèi)容,包括Hibernate、MyBatis、Spring、Spring ...
    雜貨鋪老板閱讀 1,566評(píng)論 0 2
  • 明早去吃牛肉面~~生活在蘭州,牛肉面就是一道繞不過(guò)去的坎。這是一個(gè)號(hào)稱一碗面的城市。蘭州人的一天,有很多人是從這一...
    瘦人碗子閱讀 312評(píng)論 3 7

友情鏈接更多精彩內(nèi)容