1. 概述
基于目前還是小白,那么寫過的代碼每次必會優化,我們就拿上次自己寫的數據庫框架優化一下吧。之所以自己寫一方面是因為內涵段子項目的需求問題,必須按需定制;還有一方面我想寫得更好在性能方面一定要想方設法超過第三方的開源數據庫框架。
所有分享大綱:2017Android進階之路與你同行
視頻講解地址:http://pan.baidu.com/s/1pLM1X3t
2. 開源性能對比
我從網上找了一個數據給大家看一下,分別是LitePal,AFinal,greenDAO。批量插入10000條數據,三種框架用時為:
LitePal 12882ms;
AFinal 2783ms;
greedDAO 623ms;
估計很多人觀察我很久了,早就看你不順眼了,老是盜取別人的數據。這個請見諒,我不是故意的,大家應該都還記得王自如和羅永浩的大戰,所以我就拿某個哥們的展示一下,非常感謝數據的提供。接下來我就拿我比較熟悉的LitePal和我自己的做一下對比,同樣10000條數據:
LitePal 997ms;
Darren 517ms;
以上的數據只是用來測試并不能代表什么,各位請自行忽略,請自帶馬賽克,之所以速度還行是因為按需定制,這個項目不需要寫那么麻煩,夠用就好,為什么只優化了插入部分呢?目前不能在數據庫停留太久,要加快步伐把內涵段子完結,后面有時間會做NDK數據庫加解密,懶加載等等、沒有最好只有更好。LitePal使用過的人都知道很好用,真的蠻不錯的用起來很方便,自己也看過作者郭大神很多的文章以及視頻,今天小弟黑了你實在不好意思哈哈。
3. 代碼部分
// 參數的緩存
private final Object[] mPutMethodArgs = new Object[2];
// 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[0] = putName;
mPutMethodArgs[1] = putValue;
putMethod.invoke(values, mPutMethodArgs);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 置為空
mPutMethodArgs[0] = null;
mPutMethodArgs[1] = null;
}
}
return values;
}
4. 使用方式
增刪改查,使用起來還是蠻簡單的,數據庫存放的位置在外部存儲卡中:
// 4.0 直接從工廠里面獲取daoSupport
IDaoSupport<Person> daoSupport = DaoSupportFactory.getFactory().
getDaoSupport(Person.class);
// 4.1 插入數據對象(單條)
daoSupport.insert(new Person("Darren", 23));
// 4.2 插入數據對象(批量)
List<Person> persons = new ArrayList<>();
for (int i = 0; i < 10000; 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",24);
daoSupport.upadte(person,"age = ?","23");
所有分享大綱:2017Android進階之路與你同行