淺析郭嬸兒子--LitePal架構(三),淺析--litepal
畢業半年了,Android也學習了半年了,零零散散的學了一些,漫無目的,於是看了看郭哥的<<第一行代碼>>,真心覺得不錯,對於沒有系統培訓過Android的來說,是一本很好的書籍,忘了誰問過我怎麼學Android,說實在的我也不知道,我也是個小菜,但是看過這本書之後,推薦去看一看,對於新手來說是本很好地資料,對於接觸過的人來說可以好好玩完善你的知識體系,當然沒人都有自己的認識,以上只是代表我的個人觀點.
今天我們繼續接上回講說LitePal架構源碼淺析,本部落格只是淺析,更詳細的移步到源碼那去看.
1.使用LitePal修改資料
修改單條資料:
DataSupport.update(modelClass, values, id);根據id修改資料庫內容,那我們來研究一下他的代碼
public static synchronized int update(Class<?> modelClass, ContentValues values, long id) {UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());return updateHandler.onUpdate(modelClass, id, values);}
首先獲得SQLiteDatabase,然後調用UpdateHandle中的onUpdate方法,那我們就繼續看onUpdate方法吧!
int onUpdate(Class<?> modelClass, long id, ContentValues values) {if (values.size() > 0) {return mDatabase.update(getTableName(modelClass), values, "id = " + id, null);}return 0;}
看到熟悉的代碼了,這裡就是你理解的那樣了,使用傳統資料庫的更新功能
還有另一種方法也是根據id更新資料庫的單條資料:
news.update(2);實體物件調用update方法,廢話少說直接看update源碼,估計應該和上面的onUpdate方法的代碼差不多,猜測完畢,上源碼
public synchronized int update(long id) {try {UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());int rowsAffected = updateHandler.onUpdate(this, id);getFieldsToSetToDefault().clear();return rowsAffected;} catch (Exception e) {throw new DataSupportException(e.getMessage());}}
果然不出所料,還是調用了UpdateHandle方法裡面的onUpdate方法,只是參數不相同
int onUpdate(DataSupport baseObj, long id) throws SecurityException, IllegalArgumentException,NoSuchMethodException, IllegalAccessException, InvocationTargetException {List<Field> supportedFields = getSupportedFields(baseObj.getClassName());ContentValues values = new ContentValues();putFieldsValue(baseObj, supportedFields, values);putFieldsToDefaultValue(baseObj, values);if (values.size() > 0) {return mDatabase.update(baseObj.getTableName(), values, "id = " + id, null);}return 0;}
這裡只看update,上面兩個方法主要是給value賦值,下面的部分就是傳統的操作資料庫更新的內容了.
上面主要介紹的通過id更新資料庫的單條資訊,下面介紹一下,多條資訊的更新,當然也可以使用下面方法更新單條資訊.
public static synchronized int updateAll(Class<?> modelClass, ContentValues values,String... conditions) {return updateAll(BaseUtility.changeCase(modelClass.getSimpleName()), values, conditions);}
這裡通過changeCase方法把實體名轉換成String類型的表名,具體如何?自行去看代碼吧,這裡略過,我們繼續看調用的updateAll方法
ublic static synchronized int updateAll(String tableName, ContentValues values,String... conditions) {UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());return updateHandler.onUpdateAll(tableName, values, conditions);}
又到這裡了,調用UpdateHandle方法中的onUpdateAll方法,應該跟上面的onUpdate差不多
int onUpdateAll(String tableName, ContentValues values, String... conditions) {return doUpdateAllAction(tableName, values, conditions);}
嗯?怎麼不太一樣,不要著急,我們繼續看
private int doUpdateAllAction(String tableName, ContentValues values, String... conditions) {BaseUtility.checkConditionsCorrect(conditions);if (values.size() > 0) {return mDatabase.update(tableName, values, getWhereClause(conditions),getWhereArgs(conditions));}return 0;}
又看到你熟悉的代碼了,沒錯,就是傳統的操作資料庫的方法,這裡只是把方法繼續做了封裝
當然update不止這一個方法,它還有好幾種方法,我們繼續看
public synchronized int updateAll(String... conditions) {try {UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());int rowsAffected = updateHandler.onUpdateAll(this, conditions);getFieldsToSetToDefault().clear();return rowsAffected;} catch (Exception e) {throw new DataSupportException(e.getMessage());}}
還是那個配方,還是那個味道,這裡就不敘述了,使用實體物件直接調用updateAll方法也同樣使用了上面這段代碼
2.使用LitePal刪除資料
刪除也有很多方法,當然郭哥也提供了通過id直接刪除,下面我們就先從通過id刪除資料開始看源碼
public static synchronized int delete(Class<?> modelClass, long id) {int rowsAffected = 0;SQLiteDatabase db = Connector.getDatabase();db.beginTransaction();try {DeleteHandler deleteHandler = new DeleteHandler(db);rowsAffected = deleteHandler.onDelete(modelClass, id);db.setTransactionSuccessful();return rowsAffected;} finally {db.endTransaction();}}
如果你看懂了更新是如何?,看上面的這段代碼應該很簡單,獲得SQLiteDatabase,然後開啟事務,調用DeleteHandle函數裡的onDelete方法實現刪除,如果你對上面的更新資料有印象的話,你應該猜到在onDelete方法裡面使用傳統操作資料庫的方法將資料刪除,下面貼一下代碼:
int onDelete(Class<?> modelClass, long id) {analyzeAssociations(modelClass);int rowsAffected = deleteCascade(modelClass, id);rowsAffected += mDatabase.delete(getTableName(modelClass), "id = " + id, null);getForeignKeyTableToDelete().clear();return rowsAffected;}
這裡注意一下,上面忘了說,這裡id為主鍵,增刪改查時都要操作外鍵,保證資料統一,上面這段代碼使用傳統的操作資料庫的方法刪除資料,原理和上面的差不多
當然LitePal也支援根據條件刪除資料DataSupport.deleteAll(modelClass, conditions);下面看一下源碼:
public static synchronized int deleteAll(Class<?> modelClass, String... conditions) {return deleteAll(BaseUtility.changeCase(modelClass.getSimpleName()), conditions);}
跟更新一樣先將實體轉化為string類型的表名,然後調用deleteAll方法實現根據條件刪除
private int doDeleteAllAction(String tableName, String... conditions) {BaseUtility.checkConditionsCorrect(conditions);return mDatabase.delete(tableName, getWhereClause(conditions), getWhereArgs(conditions));}
同樣的實體物件調用delete方法也跟更新類似
public static synchronized int delete(Class<?> modelClass, long id) {int rowsAffected = 0;SQLiteDatabase db = Connector.getDatabase();db.beginTransaction();try {DeleteHandler deleteHandler = new DeleteHandler(db);rowsAffected = deleteHandler.onDelete(modelClass, id);db.setTransactionSuccessful();return rowsAffected;} finally {db.endTransaction();}}
如果上面你都看懂了的話,看到這段代碼你應該很高興,好了,今天就先扯這麼多,現在你應該對LitePal架構比較瞭解了,後續還會更新,有疑問的留言撒~~~