天天看點

自己動手寫DB資料庫架構(性能優化)

1. 概述

  基于目前還是小白,那麼寫過的代碼每次必會優化,我們就拿上次自己寫的資料庫架構優化一下吧。之是以自己寫一方面是因為内涵段子項目的需求問題,必須按需定制;還有一方面我想寫得更好在性能方面一定要想方設法超過第三方的開源資料庫架構。

所有分享大綱:2017Android進階之路與你同行

視訊講解位址:http://pan.baidu.com/s/1eSj5cdk

自己動手寫DB資料庫架構(性能優化)

    

2. 開源性能對比

  我從網上找了一個資料給大家看一下,分别是LitePal,AFinal,greenDAO。批量插入10000條資料,三種架構用時為:

LitePal          12882ms;
AFinal           2783ms;
greedDAO         623ms;
           

  估計很多人觀察我很久了,早就看你不順眼了,老是盜取别人的資料。這個請見諒,我不是故意的,大家應該都還記得王自如和羅永浩的大戰,是以我就拿某個哥們的展示一下,非常感謝資料的提供。接下來我就拿我比較熟悉的LitePal和我自己的做一下對比,同樣10000條資料:

LitePal          997ms;
Darren           517ms;
           

  以上的資料隻是用來測試并不能代表什麼,各位請自行忽略,請自帶馬賽克,為什麼隻優化了插入部分呢?目前不能在資料庫停留太久,要加快步伐把内涵段子完結,後面有時間會做NDK資料庫加解密,懶加載等等、沒有最好隻有更好。

 

3. 代碼部分

// 參數的緩存
    private final Object[] mPutMethodArgs = new Object[];
    // put反射方法的緩存
    private static final Map<Class<?>, Method> mInputMethods
            = new ArrayMap<>();

    // 批量插入
    @Override
    public void insert(List<T> list) {
        mSqLiteDatabase.beginTransaction();
        for (T t : list) {
            insert(t);
        }
        mSqLiteDatabase.setTransactionSuccessful();
        mSqLiteDatabase.endTransaction();
    }

    // 單條插入
    @Override
    public long insert(T obj) {
         ContentValues values = transformContentValue(obj);
         return mSqLiteDatabase.insert(DBUtils.getTableName(mClass), null, values);
    }

     /**
     * 把Object轉換成ContentValues
     *
     * @return ContentValues
     */
    private ContentValues transformContentValue(T obj) {
        ContentValues values = new ContentValues();
        Field[] fields = mClass.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                // 通過反射擷取字段名和字段值
                String putName = field.getName();
                Object putValue = field.get(obj);
                if (putValue == null) {
                    continue;
                }

                // 感謝google提供的源碼,很快我們又會再見
                Class<?> putValueClass = putValue.getClass();
                Method putMethod = mPutMethods.get(putValueClass);
                // 從緩存裡面擷取
                if (putMethod == null) {
                    putMethod = ContentValues.class.getMethod("put",
                            String.class, putValueClass);
                    mPutMethods.put(putValueClass, putMethod);
                }
                // 反射執行方法
                mPutMethodArgs[] = putName;
                mPutMethodArgs[] = putValue;
                putMethod.invoke(values, mPutMethodArgs);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 置為空
                mPutMethodArgs[] = null;
                mPutMethodArgs[] = null;
            }
        }
        return values;
    }
           

4. 使用方式

  增删改查,使用起來還是蠻簡單的,資料庫存放的位置在外部存儲卡中:

// 4.0 直接從工廠裡面擷取daoSupport 
IDaoSupport<Person> daoSupport = DaoSupportFactory.getFactory().
        getDaoSupport(Person.class);

// 4.1 插入資料對象(單條)
daoSupport.insert(new Person("Darren", ));

// 4.2 插入資料對象(批量)
List<Person> persons = new ArrayList<>();
for (int i = ; i < ; i++) {
    persons.add(new Person("darren", "23"));
}
daoSupport.insert(persons);

// 4.3 查詢所有
List<Person> persons = daoSupport.querySupport().queryAll();

// 4.4 根據條件進行查詢
List<Person> persons = daoSupport.querySupport()
    .selection("age = ?").selectionArgs("23").query();

// 4.5 根據條件進行删除
daoSupport.delete("age = ?","23");

// 4.6 根據條件進行更新
Person person = new Person("Jack",);
daoSupport.upadte(person,"age = ?","23");
           

所有分享大綱:2017Android進階之路與你同行

視訊講解位址:http://pan.baidu.com/s/1eSj5cdk