史上最全greendao源碼解析



greendao 是目前很流行的一個數據庫,既然那麼流行,那麼多人用,我們就來看看它的實現的原理,它的優勢所在。

如果還不知道怎麼配置的,請看我的上一篇博客。


先不多說,上一個類的結構圖,一目瞭然:



這是greendao的使用入口

 DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(getApplicationContext(), "MMCD.db", null); //SQLiteOpenHelper
 DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
        daoSession = daoMaster.newSession();

一般這個是放在Application裏面,得到session那麼就可以操作數據庫了,也可以拿到dao 再對數據庫進行crud,至於類與類之間的關係,上面的圖已經很清楚,就不再這裏贅述了。



greendao牛逼之處在於可以直接傳入對象進行crud,非常靈活,後面最終的操作還是拼接的sql,讓我慢慢來揭開它的神祕面紗。


在DaoSession 初始化的時候,registerDao(User.class, userDao);將實體和dao註冊在map中,一邊後邊通過對象獲取dao,

這樣在DaoSession 中也可以調用dao的方法對數據庫進行操作。



看看代碼很直觀,簡單易懂。

/** Convenient call for {@link AbstractDao#loadAll()}. */
    public <T, K> List<T> loadAll(Class<T> entityClass) {
        @SuppressWarnings("unchecked")
        AbstractDao<T, K> dao = (AbstractDao<T, K>) getDao(entityClass);
        return dao.loadAll();
    }



    public AbstractDao<?, ?> getDao(Class<? extends Object> entityClass) {
        AbstractDao<?, ?> dao = entityToDao.get(entityClass);
        if (dao == null) {
            throw new DaoException("No DAO registered for " + entityClass);
        }
        return dao;
    }





回到dao中,首先dao的loadAll(查詢所有數據) 直接調用的

 /** Loads all available entities from the database. */
    public List<T> loadAll() {
        Cursor cursor = db.rawQuery(statements.getSelectAll(), null);
        return loadAllAndCloseCursor(cursor);
    }


 /** ends with an space to simplify appending to this string. */
    public String getSelectAll() {
        if (selectAll == null) {
            selectAll = SqlUtils.createSqlSelect(tablename, "T", allColumns, false); //不出意外這個是在拼接sql
        }
        return selectAll;
    }


sql拼接關鍵代碼



   /** Creates an select for given columns with a trailing space */
    public static String createSqlSelect(String tablename, String tableAlias, String[] columns, boolean distinct) {
        if (tableAlias == null || tableAlias.length() < 0) {
            throw new DaoException("Table alias required");
        }


        StringBuilder builder = new StringBuilder(distinct ? "SELECT DISTINCT " : "SELECT ");
        SqlUtils.appendColumns(builder, tableAlias, columns).append(" FROM ");
        builder.append('"').append(tablename).append('"').append(' ').append(tableAlias).append(' ');
        return builder.toString();
    }


好了代碼就放這麼多吧,其他的方法也是一樣,包括裏面用的異步查找,按照這樣的方式 一步步看看很直觀。


以上是本人查看源碼的總結的,本人能力有限,肯定有很多錯誤的地方,理解不到位的地方,還請大神們指出來,共同進步。。




猛戳這裏點擊關注公衆號⬇️ 即可瞭解我們更多: