Room数据库包装-通过kotlin包装一行代码增删改查

本文目的在于,针对room原生api中有一些不方便的地方,基于注解与RxJava,kotlin的强大lambda表达式进行包装节省大量开发工作。

谷歌发布了ROOM数据库,与其他常见数据库api的区别是,基于注解与sql,不需要像其他库一样去记数据库内置的DAO的各种操作api函数,数据库迁移功能很强大而且逻辑清晰,便于维护。官方支持RxJava,对于查询结果可以很方便的实现异步订阅。

Room提供给我们的是一个基础的有无限可能的库,也许对于新手程序员来说,不如greendao等库用起来足够傻瓜式(只需要记住增删改查的api,不需要自己去写dao的sql语句),但是谷歌的库都有一个特点,就是基于你的能力,可以有无限的扩展可能(databinding库也是类似,新手觉得没有便捷多少,但是如果你自己积累,编写了很多自定义xml属性,和自己改造包装通用的工具方法,databinding甚至可以让给你在xml中一行属性完成listView的adapter从创建,填充数据一条龙服务,这点稍后会把我的基于databinding的包装心得写一篇文章,抛砖引玉,启发大家想出天马行空的使用方式)。关于数据库的使用不做过于详细的讲解,我这里只对于从0开始组建room数据库实践过程中的心得,如何利用。

关于ROOM的痛点:

1.对比与其他的开源数据库,在创建dao的时候,需要手动写增删该查,如果表很多,也有不小的工作量。

2.不进行包装,原生使用方式基于Dao对象操作,对于增删改查都要写大量的rxJava的订阅监听以及线程的模版代码,这些都可以通过技术手段简化,避免。

github地址:

GitHub - chrism1981/fastRoomDatabase: Room Database for Android, with kotlin. 基于room数据库的包装,快速开发,一行代码增删改查

一.下面我们来看一下原生的Room使用过程(归结为:Entity,Dao,DataBase三大对象):

1.对数据对象进行@entity注解处理,转化为Entity类:比较简单,class上标记@Entity,对于主键变量,标记@PrimaryKey

2.根据Entity对象,创建对应对DAO类,通过注解的方式,将SQL(不用害怕敲sql,用room库的话,在敲sql的时候也是有代码提示的,不会像写纯string一样出现笔误等情况。)语句注册给对应对操作方法:


3. 创建自己的DataBase类(继承RoomDatabase),声明你之前创建的dao的操作方法


4.以查询方法为例子,api的实际调用:获取数据库实例,获取dao实例,操作dao的方法。

二.本文的包装思路与实际操作预览:

下面是我的包装方法:首先解决不必要重复写的增删等方法。然后已一个DataBaseHelper类来包装,操作数据库,将rxjava的订阅过程包装起来,并且引入带参数的查询。

主要解决问题就是免去大量的模版代码,rxjava代码,线程操作,数据库操作,都由

最终预览下,我们想调用一个SearchRecordDao来查询,获取到一个结果list,显示到一个textview上,最终的全部代码如下:

一行代码完成查询过程,不用关心数据库如何创建,dao如何创建,异步线程操作等等都不需要在开发时候重复去操作了。

三.大致结构与流程:

结构:

流程:


四. 主要代码讲解:

1.Dao类注解的标记:

其中@IsQuery :无参数查询所有数据;@IsQueryWithKey 带一个参数的查询,@IsDeleteAll :删除全部。 以上这些方法的Sql其实都可以copy,只是表名不同。


2.DBHelper 中的工作:

当这个Dao被创建标记完成以后,我们马上就可以通过操作 DBHelper来进行操作这个表的查询,比如要调用通过 id查询结果(getSearchRecordById()方法):传一个key,Dao的class,成功获取结果后的回调函数(lambda表达式)

这个调用对应都就是我们刚才在SearchRecordDao.class里的getResearchRecordById()方法,它是通过注解 @ IsQueryWithKey被识别,当我们调用时候传的“1270030”就是id参数。

首先,通过DBHelper找到dao,然后调用dao的对应带参数查询方法,数据库的关闭也在这里进行。queryListWithKey方法如下:

其中的success 和fail 类型为 (t:List)->(Unit)这个代表一个lambda表达式,

对于lambda不熟悉的同学,我简答讲解下怎么理解这个东西。

当这个表达式success(t)被调用的时候,这个方法的设计者会把他查询到的结果(一个list<T>)通过invoke这个表达式的方式传递给你,以便于你的表达式在编写的时候,就可以针对这个查询结果出来以后,如何进行下一步工作给出方案。其中suceess(t) 就是调用lambda表达式,其实它和调用函数是一样的。如果熟悉c,c++的同学,可以发现,它和函数指针的概念很像。

对于用java的同学,可以这样对照lambda和匿名内部类:

{  list-> int size = list.size() }  可以这样理解 ,假设又一个Success接口包含一个参数为list的方法,

success = new Success(){  

@override

public void recall(List<T> list){

int size = list.size();

} }

其实任何一个lambda表达式,都可以用一个接口来代替。而相对于接口,lambda可以说,是去掉了定义接口类,创建匿名对象这一过程,可以用一个式子来完成全部工作。

3.Dao中的代码:

dao中的具体实现方法,都在BaseDao中,由父类实现了 insert,delete ,update等方法。子类中主要就是声明query方法,并用注解中写好Sql语句。

BaseDao:

这个方法虽然是在BaseDao中,但我们但子类Dao中会继承这个方法,当它在运行时候,反射获取的所有method是当前子类的所有方法,这样我们在写BaseDao的时候,就可以实现找到将来任意一个子类中代表了有参查询@IsQueryWithKey的方法,并且调用这个方法,在父类里就预先写好RxJava的订阅。

最后的结果就是使用时候直接调用DbHepler.queryWithKey(..),然后Dbhelper会自己去找到BaseDao的query方法,BaseDao在找到当前子类Dao的query方法。完成查询。

总结:当然这只是一个思路,满足大部分app中数据库简单应用,比如一些复杂的sql语句查询,肯定会有,但不会是每一条查询都是复杂的。我们简化包装,如果可以覆盖一半以上的应用场景,那它就是值得的。

后期还有很多可以扩展的地方,比如带参数的查询,可以扩展到多个参数,同一个Dao中,可能需要多个含单参数查询的方法,比如按name查询,按age查询,我们同样可以扩展实现,比如在@IsQueryWithKey注解中接受参数,注解可以接受基础数据类型和枚举。 这样一来,对于2个不同的单参数查询方法,可以用 @IsQueryWithKey(name) 和@IsQueryWithKey(age)来标记不同方法,在项目中也可以维护一个常量表,用于代表这些查询参数,这样在调用Dbhelper来查询的时候,通过传入对于参数,就可以区分当前想要查询的条件是什么。

最后附上地址

github地址:

GitHub - chrism1981/fastRoomDatabase: Room Database for Android, with kotlin. 基于room数据库的包装,快速开发,一行代码增删改查

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容