在上一篇博客[《打造android ORM框架opendroid(四)——優雅的刪除數據》](http://blog.csdn.net/qibin0506/article/details/43083057)中,我們介紹了opendroid是如何優雅的從數據庫中刪除數據的,也可以看到opendroid的設計是如此的簡單,其實[opendroid](http://git.oschina.net/qibin/OpenDroid)只是我作為興趣或者說是抱著試試的態度寫的,當然它肯定存在諸多不足,但是這并不影響我們去了解一個orm框架的流程。
廢話不說了,下面進入主題,今天我選擇去了解的是opendroid的update流程,其實,對于已經了解了delete操作的朋友們來說,今天的update流程肯定是如此的熟悉,因為它的大體流程和delete操作基本一致, 只是多了一步數據的對應。
按照慣例,我們先來熟悉一下opendroid是如何更新一條數據的。
~~~
Student?stu?=?new?Student();????
stu.setStuName("loader");????
stu.update(4);???
~~~
~~~
Student?stu?=?new?Student();????
stu.setStuName("loader");????
stu.update("_id>?",?"4");??
~~~
~~~
ContentValues?cv?=?new?ContentValues();????
cv.put("stuName",?"loader");????
OpenDroid.update(Student.class,?cv,?"_id>??or?name?like??",?"1",?"%q%");??
~~~
好了,opendroid就提供了這三種方式的更新操作。其中第三種是使用ContentValues的形式更新,相信大家肯定很熟悉了。
哦對了,提前透漏一下,其實和delete一樣,這三種方式最后還是會歸位到一個方法上。
首先我們來定位到第一個update的源碼上。
~~~
/**??
?*?更新數據??
?*?@param?ids?要更新數據的id??
?*?@return?影響行數??
?*/????
public?int?update(int...?ids)?{????
????try?{????
????????Class?klass?=?(Class)?getClass();????
????????ContentValues?cv?=?new?ContentValues();????
????????generateData(klass,?cv);????
????????????????
????????if(ids.length?==?0)?{????
????????????return?update(klass,?cv,?null,?null);????
????????}????
????????????????
????????StringBuilder?builder?=?new?StringBuilder("_id?in?(");????
????????String[]?whereArgs?=?new?String[ids.length];????
????????buildIn(builder,?whereArgs,?ids);????
????????????????
????????return?update(klass,?cv,?builder.toString(),?whereArgs);????
????}?catch?(Exception?e)?{????
????????e.printStackTrace();????
????}????
????return?-1;????
}??
~~~
第8行,我們獲取了當前對象的Class,目的就是要通過反射來獲取它里面的字段和名字。
接下來new了一個ContentValues對象,還記得上面我說過“這三種方式最后還是會歸位到一個方法上“, 從這里我們大體可以猜到,最后都歸位到
` OpenDroid.update(Student.class,?cv,?"_id>??or?name?like??",?"1",?"%q%");??`
??這個方法上了。保留著這個猜測,繼續分析代碼。
緊接著一個generateData方法,這個方法我們曾經在[《打造android ORM框架opendroid(三)——持久化數據》](http://blog.csdn.net/qibin0506/article/details/42872361)中詳細的去分析過,如果你好不清楚這個方法的作用,可以去參考前面的博客。
12~14行,通過判斷如果沒有傳任何id,則可能是更新全部數據,這里調用了靜態的update方法,最后兩個參數都傳的null。
16~18這三行代碼,大家應該還熟悉了吧,我們在講解delete的時候也有這么三句話,這三句話就是構建一個in的sql語句,并設置它的參數,如果你不太熟悉它,可以參考[《打造android ORM框架opendroid(四)——優雅的刪除數據》](http://blog.csdn.net/qibin0506/article/details/43083057),這篇博客中對buildIn方法也做了說明,這里就不重復去說了。
該方法的最后,同樣調用了一個靜態的update方法,并返回了影響行數。
接下來,我們來定位到第二個update方法中一探究竟!
~~~
/**??
?*?更新數據??
?*?@param?where?條件??
?*?@param?whereArgs?條件參數??
?*?@return?影響行數??
?*/????
public?int?update(String?where,?String...?whereArgs)?{????
????try?{????
????????Class?klass?=?(Class)?getClass();????
????????ContentValues?cv?=?new?ContentValues();????
????????generateData(klass,?cv);????
????????????????
????????return?update(klass,?cv,?where,?whereArgs);????
????}?catch?(Exception?e)?{????
????????e.printStackTrace();????
????}????
????return?-1;????
}??
~~~
其實這個方法和上面的很想,只是上面的需要在update方法里去組合條件,而這里的條件由用戶傳入,所以這個方法我們也不多講了,接下來我們來看看三兄弟會合的地方,也就是第三方方式調用的那個靜態方法!(哦,對了,這里驗證上面我們那個猜測是正確的!)
~~~
/**??
?*?更新數據??
?*?@param?klass?要更新的表對應的class??
?*?@param?cv?要更新的數據??
?*?@param?where?where條件??
?*?@param?whereArgs?條件的參數??
?*?@return?影響行數??
?*/????
public?static?extends?OpenDroid>?int?update(Class?klass,?ContentValues?cv,????
????????String?where,?String...?whereArgs)?{????
????String?tableName?=?klass.getSimpleName();????
????return?CRUD.update(tableName,?cv,?where,?whereArgs,?sSqliteDatabase);????
}??
~~~
對于代碼控來說,確實夠令人失望了,代碼只有兩行!還沒有注釋多! 尼瑪!(心里,千萬只草泥馬飛奔而過)
1/2行代碼獲取了klass的類名,也就是我們要操作的表名。
2/2行,直接調用了CRUD.update方法去更新數據庫,又是CRUD...我們去看看吧。
~~~
/**??
?*?更新數據??
?*?@param?tableName?表名??
?*?@param?cv?更新的數據??
?*?@param?where?更新的條件??
?*?@param?whereArgs?更新的條件參數??
?*?@param?db?數據庫??
?*?@return?影響行數??
?*/????
protected?static?extends?OpenDroid>?int?update(String?tableName,?ContentValues?cv,????
????????String?where,?String[]?whereArgs,?SQLiteDatabase?db)?{????
????int?count?=?db.update(tableName,?cv,?where,?whereArgs);????
????return?count;????
}??
~~~
好吧,又是兩行代碼, 而且直接調用了SQLiteDatabase的update方法去更新數據,走到這一步,要使用的數據肯定已經都準備好了。tableName我們在前面已經獲取了,ContentValues是用過generateData來填充的或者用戶自己new的,where和whereArgs不管是根據id更新還是通過條件更新的,我們都已經確定了。這里只需要調用android原生的update方法去更新數據庫就ok了,最后返回了影響行數。
今天的update操作確實夠簡單,原因是,我們的很多代碼都是在前面幾篇博客中詳細說明了,如果你還不清楚里面的一些細節,可以再花幾分鐘去看看前面的幾篇博客。
來總結一下opendroid的update流程吧。
1、在業務邏輯中可以通過三種update方法去更新數據,除了一種靜態的,另外兩種都需要在bean對象上操作。
2、不管哪種操作,最后都會到OpenDroid.update(Class klass, ContentValues cv,String where, String... whereArgs)這個方法上。
3、接著通過CRUD.update方法來調用android原生的upate方法來更新數據庫,并依次返回影響行數。
在完成了update操作的分析后,opendroid的基本操作已經完成了一大部分,現在只剩下select操作沒去分析,相信大家現在完全可以照這opendroid的思路去做一個自己的ORM框架了。當然,下面的博客還會繼續完成select操作的分析,當然還會有opendroid的數據庫升級機制。
opendroid的開源地址:[http://git.oschina.net/qibin/OpenDroid](http://git.oschina.net/qibin/OpenDroid)