Room數(shù)據(jù)庫(kù)包裝-通過(guò)kotlin包裝一行代碼增刪改查

本文目的在于,針對(duì)room原生api中有一些不方便的地方,基于注解與RxJava孙援,kotlin的強(qiáng)大lambda表達(dá)式進(jìn)行包裝節(jié)省大量開(kāi)發(fā)工作害淤。

谷歌發(fā)布了ROOM數(shù)據(jù)庫(kù),與其他常見(jiàn)數(shù)據(jù)庫(kù)api的區(qū)別是拓售,基于注解與sql窥摄,不需要像其他庫(kù)一樣去記數(shù)據(jù)庫(kù)內(nèi)置的DAO的各種操作api函數(shù),數(shù)據(jù)庫(kù)遷移功能很強(qiáng)大而且邏輯清晰础淤,便于維護(hù)崭放。官方支持RxJava,對(duì)于查詢(xún)結(jié)果可以很方便的實(shí)現(xiàn)異步訂閱鸽凶。

Room提供給我們的是一個(gè)基礎(chǔ)的有無(wú)限可能的庫(kù)莹菱,也許對(duì)于新手程序員來(lái)說(shuō),不如greendao等庫(kù)用起來(lái)足夠傻瓜式(只需要記住增刪改查的api吱瘩,不需要自己去寫(xiě)dao的sql語(yǔ)句)道伟,但是谷歌的庫(kù)都有一個(gè)特點(diǎn),就是基于你的能力使碾,可以有無(wú)限的擴(kuò)展可能(databinding庫(kù)也是類(lèi)似蜜徽,新手覺(jué)得沒(méi)有便捷多少,但是如果你自己積累票摇,編寫(xiě)了很多自定義xml屬性拘鞋,和自己改造包裝通用的工具方法,databinding甚至可以讓給你在xml中一行屬性完成listView的adapter從創(chuàng)建矢门,填充數(shù)據(jù)一條龍服務(wù)盆色,這點(diǎn)稍后會(huì)把我的基于databinding的包裝心得寫(xiě)一篇文章,拋磚引玉祟剔,啟發(fā)大家想出天馬行空的使用方式)隔躲。關(guān)于數(shù)據(jù)庫(kù)的使用不做過(guò)于詳細(xì)的講解,我這里只對(duì)于從0開(kāi)始組建room數(shù)據(jù)庫(kù)實(shí)踐過(guò)程中的心得物延,如何利用宣旱。

關(guān)于ROOM的痛點(diǎn):

1.對(duì)比與其他的開(kāi)源數(shù)據(jù)庫(kù),在創(chuàng)建dao的時(shí)候叛薯,需要手動(dòng)寫(xiě)增刪該查浑吟,如果表很多,也有不小的工作量耗溜。

2.不進(jìn)行包裝组力,原生使用方式基于Dao對(duì)象操作,對(duì)于增刪改查都要寫(xiě)大量的rxJava的訂閱監(jiān)聽(tīng)以及線程的模版代碼抖拴,這些都可以通過(guò)技術(shù)手段簡(jiǎn)化燎字,避免。

github地址:

GitHub - chrism1981/fastRoomDatabase: Room Database for Android, with kotlin. 基于room數(shù)據(jù)庫(kù)的包裝,快速開(kāi)發(fā)轩触,一行代碼增刪改查

一.下面我們來(lái)看一下原生的Room使用過(guò)程(歸結(jié)為:Entity,Dao家夺,DataBase三大對(duì)象):

1.對(duì)數(shù)據(jù)對(duì)象進(jìn)行@entity注解處理脱柱,轉(zhuǎn)化為Entity類(lèi):比較簡(jiǎn)單,class上標(biāo)記@Entity拉馋,對(duì)于主鍵變量榨为,標(biāo)記@PrimaryKey

2.根據(jù)Entity對(duì)象,創(chuàng)建對(duì)應(yīng)對(duì)DAO類(lèi)煌茴,通過(guò)注解的方式随闺,將SQL(不用害怕敲sql,用room庫(kù)的話蔓腐,在敲sql的時(shí)候也是有代碼提示的矩乐,不會(huì)像寫(xiě)純string一樣出現(xiàn)筆誤等情況。)語(yǔ)句注冊(cè)給對(duì)應(yīng)對(duì)操作方法:


3. 創(chuàng)建自己的DataBase類(lèi)(繼承RoomDatabase)回论,聲明你之前創(chuàng)建的dao的操作方法


4.以查詢(xún)方法為例子散罕,api的實(shí)際調(diào)用:獲取數(shù)據(jù)庫(kù)實(shí)例,獲取dao實(shí)例傀蓉,操作dao的方法欧漱。

二.本文的包裝思路與實(shí)際操作預(yù)覽:

下面是我的包裝方法:首先解決不必要重復(fù)寫(xiě)的增刪等方法。然后已一個(gè)DataBaseHelper類(lèi)來(lái)包裝葬燎,操作數(shù)據(jù)庫(kù)误甚,將rxjava的訂閱過(guò)程包裝起來(lái),并且引入帶參數(shù)的查詢(xún)谱净。

主要解決問(wèn)題就是免去大量的模版代碼窑邦,rxjava代碼,線程操作壕探,數(shù)據(jù)庫(kù)操作奕翔,都由

最終預(yù)覽下,我們想調(diào)用一個(gè)SearchRecordDao來(lái)查詢(xún)浩蓉,獲取到一個(gè)結(jié)果list派继,顯示到一個(gè)textview上,最終的全部代碼如下:

一行代碼完成查詢(xún)過(guò)程捻艳,不用關(guān)心數(shù)據(jù)庫(kù)如何創(chuàng)建驾窟,dao如何創(chuàng)建,異步線程操作等等都不需要在開(kāi)發(fā)時(shí)候重復(fù)去操作了认轨。

三.大致結(jié)構(gòu)與流程:

結(jié)構(gòu):

流程:


四. 主要代碼講解:

1.Dao類(lèi)注解的標(biāo)記:

其中@IsQuery :無(wú)參數(shù)查詢(xún)所有數(shù)據(jù)绅络;@IsQueryWithKey 帶一個(gè)參數(shù)的查詢(xún),@IsDeleteAll :刪除全部。 以上這些方法的Sql其實(shí)都可以copy恩急,只是表名不同杉畜。


2.DBHelper 中的工作:

當(dāng)這個(gè)Dao被創(chuàng)建標(biāo)記完成以后,我們馬上就可以通過(guò)操作 DBHelper來(lái)進(jìn)行操作這個(gè)表的查詢(xún)衷恭,比如要調(diào)用通過(guò) id查詢(xún)結(jié)果(getSearchRecordById()方法):傳一個(gè)key此叠,Dao的class,成功獲取結(jié)果后的回調(diào)函數(shù)(lambda表達(dá)式)

這個(gè)調(diào)用對(duì)應(yīng)都就是我們剛才在SearchRecordDao.class里的getResearchRecordById()方法随珠,它是通過(guò)注解 @ IsQueryWithKey被識(shí)別灭袁,當(dāng)我們調(diào)用時(shí)候傳的“1270030”就是id參數(shù)。

首先窗看,通過(guò)DBHelper找到dao茸歧,然后調(diào)用dao的對(duì)應(yīng)帶參數(shù)查詢(xún)方法,數(shù)據(jù)庫(kù)的關(guān)閉也在這里進(jìn)行显沈。queryListWithKey方法如下:

其中的success 和fail 類(lèi)型為 (t:List)->(Unit)這個(gè)代表一個(gè)lambda表達(dá)式软瞎,

對(duì)于lambda不熟悉的同學(xué),我簡(jiǎn)答講解下怎么理解這個(gè)東西拉讯。

當(dāng)這個(gè)表達(dá)式success(t)被調(diào)用的時(shí)候铜涉,這個(gè)方法的設(shè)計(jì)者會(huì)把他查詢(xún)到的結(jié)果(一個(gè)list<T>)通過(guò)invoke這個(gè)表達(dá)式的方式傳遞給你,以便于你的表達(dá)式在編寫(xiě)的時(shí)候遂唧,就可以針對(duì)這個(gè)查詢(xún)結(jié)果出來(lái)以后芙代,如何進(jìn)行下一步工作給出方案。其中suceess(t) 就是調(diào)用lambda表達(dá)式盖彭,其實(shí)它和調(diào)用函數(shù)是一樣的纹烹。如果熟悉c,c++的同學(xué)召边,可以發(fā)現(xiàn)铺呵,它和函數(shù)指針的概念很像。

對(duì)于用java的同學(xué)隧熙,可以這樣對(duì)照l(shuí)ambda和匿名內(nèi)部類(lèi):

{? list-> int size = list.size() }? 可以這樣理解 片挂,假設(shè)又一個(gè)Success接口包含一個(gè)參數(shù)為list的方法扮惦,

success = new Success(){??

@override

public void recall(List<T> list){

int size = list.size();

} }

其實(shí)任何一個(gè)lambda表達(dá)式铅檩,都可以用一個(gè)接口來(lái)代替耘子。而相對(duì)于接口姨丈,lambda可以說(shuō),是去掉了定義接口類(lèi)扫腺,創(chuàng)建匿名對(duì)象這一過(guò)程砌创,可以用一個(gè)式子來(lái)完成全部工作姆打。

3.Dao中的代碼:

dao中的具體實(shí)現(xiàn)方法件余,都在BaseDao中讥脐,由父類(lèi)實(shí)現(xiàn)了 insert遭居,delete ,update等方法旬渠。子類(lèi)中主要就是聲明query方法俱萍,并用注解中寫(xiě)好Sql語(yǔ)句。

BaseDao:

這個(gè)方法雖然是在BaseDao中告丢,但我們但子類(lèi)Dao中會(huì)繼承這個(gè)方法枪蘑,當(dāng)它在運(yùn)行時(shí)候,反射獲取的所有method是當(dāng)前子類(lèi)的所有方法芋齿,這樣我們?cè)趯?xiě)B(tài)aseDao的時(shí)候,就可以實(shí)現(xiàn)找到將來(lái)任意一個(gè)子類(lèi)中代表了有參查詢(xún)@IsQueryWithKey的方法,并且調(diào)用這個(gè)方法成翩,在父類(lèi)里就預(yù)先寫(xiě)好RxJava的訂閱觅捆。

最后的結(jié)果就是使用時(shí)候直接調(diào)用DbHepler.queryWithKey(..),然后Dbhelper會(huì)自己去找到BaseDao的query方法麻敌,BaseDao在找到當(dāng)前子類(lèi)Dao的query方法栅炒。完成查詢(xún)。

總結(jié):當(dāng)然這只是一個(gè)思路术羔,滿(mǎn)足大部分app中數(shù)據(jù)庫(kù)簡(jiǎn)單應(yīng)用赢赊,比如一些復(fù)雜的sql語(yǔ)句查詢(xún),肯定會(huì)有级历,但不會(huì)是每一條查詢(xún)都是復(fù)雜的释移。我們簡(jiǎn)化包裝,如果可以覆蓋一半以上的應(yīng)用場(chǎng)景寥殖,那它就是值得的玩讳。

后期還有很多可以擴(kuò)展的地方,比如帶參數(shù)的查詢(xún)嚼贡,可以擴(kuò)展到多個(gè)參數(shù)熏纯,同一個(gè)Dao中,可能需要多個(gè)含單參數(shù)查詢(xún)的方法粤策,比如按name查詢(xún)樟澜,按age查詢(xún),我們同樣可以擴(kuò)展實(shí)現(xiàn)叮盘,比如在@IsQueryWithKey注解中接受參數(shù)秩贰,注解可以接受基礎(chǔ)數(shù)據(jù)類(lèi)型和枚舉。 這樣一來(lái)柔吼,對(duì)于2個(gè)不同的單參數(shù)查詢(xún)方法萍膛,可以用 @IsQueryWithKey(name) 和@IsQueryWithKey(age)來(lái)標(biāo)記不同方法,在項(xiàng)目中也可以維護(hù)一個(gè)常量表嚷堡,用于代表這些查詢(xún)參數(shù)蝗罗,這樣在調(diào)用Dbhelper來(lái)查詢(xún)的時(shí)候艇棕,通過(guò)傳入對(duì)于參數(shù),就可以區(qū)分當(dāng)前想要查詢(xún)的條件是什么串塑。

最后附上地址

github地址:

GitHub - chrism1981/fastRoomDatabase: Room Database for Android, with kotlin. 基于room數(shù)據(jù)庫(kù)的包裝沼琉,快速開(kāi)發(fā),一行代碼增刪改查

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末桩匪,一起剝皮案震驚了整個(gè)濱河市打瘪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌傻昙,老刑警劉巖闺骚,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異妆档,居然都是意外死亡僻爽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)贾惦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)胸梆,“玉大人,你說(shuō)我怎么就攤上這事须板∨鼍担” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵习瑰,是天一觀的道長(zhǎng)绪颖。 經(jīng)常有香客問(wèn)我,道長(zhǎng)甜奄,這世上最難降的妖魔是什么菠发? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮贺嫂,結(jié)果婚禮上滓鸠,老公的妹妹穿的比我還像新娘。我一直安慰自己第喳,他們只是感情好糜俗,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著曲饱,像睡著了一般悠抹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扩淀,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天楔敌,我揣著相機(jī)與錄音,去河邊找鬼驻谆。 笑死卵凑,一個(gè)胖子當(dāng)著我的面吹牛庆聘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勺卢,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼伙判,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了黑忱?” 一聲冷哼從身側(cè)響起宴抚,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甫煞,沒(méi)想到半個(gè)月后菇曲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抚吠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年常潮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埃跷。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蕊玷,死狀恐怖邮利,靈堂內(nèi)的尸體忽然破棺而出弥雹,到底是詐尸還是另有隱情,我是刑警寧澤延届,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布剪勿,位于F島的核電站,受9級(jí)特大地震影響方庭,放射性物質(zhì)發(fā)生泄漏厕吉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一械念、第九天 我趴在偏房一處隱蔽的房頂上張望头朱。 院中可真熱鬧,春花似錦龄减、人聲如沸项钮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)烁巫。三九已至,卻和暖如春宠能,著一層夾襖步出監(jiān)牢的瞬間亚隙,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工违崇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阿弃,地道東北人诊霹。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像恤浪,于是被迫代替她去往敵國(guó)和親畅哑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容