首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring Boot项目通用功能之《通用service第一讲》

前言思考

首先我们先思考一下,对于SERVICE层有哪些是可以被公共出来的东西?好,我先来说几个:

对于单张表的增、删、改、查(单条查、批量查、分页查)功能

单张表的增、删、改、查功能相对应的缓存功能(缓存有很多方式:ehcache缓存、redis缓存等等)

对数状结构的表操作(树状结构比较常见,比如:后台权限用到的资源树表、地域城市表、组织架构表等等的业务场景)

很多的主功能业务表中可能会增加一个扩展字段用于存储附加属性,那如果我们把这种key->value结构关系单独抽离一个功能,来简化我们对这种附加属性的使用,是不是会更好呢(比如:在order表中,总是有一些并不是所有订单都会有的属性,这时我们可能会将这些属性存储在一个叫ext的字段中,格式可能是json格式的字符串也可能是key:value这种数据结构,但是想想这种方式的存储是不是很不利于结构化搜索,而且还要在主表上维护扩展属性的增删改查功能,抽离下公共功能的附加表是个很好的方式)

好了,上面说了几点关于业务逻辑层我们可能会有哪些公共的逻辑可以被抽离,在企业开发中,可不仅仅是这样,对于不同的公司业务也都有很大差异,所以你也可以向我一样思考一下,在你的企业里,有哪些像上述所说的功能可以被抽离的呢?

实现上述思考

因为篇幅有限,所以对于通用service我们会分几篇文章来详细讲解下,本章我们只说一下我们的思考1:对于单张表的增、删、改、查功能。那好,我们在紧接着想想,既然是要抽离单张表增删改查SERVICE层,那我们肯定是要有一个相对通用的DAO层来完成与数据库的沟通了,没错,我们就是借助上篇讲到的通用Mapper来实现的。下面让我们来看下具体的代码实现。

PO类统一接口:

备注

PO类(也就是数据库表对应的实体类)的统一接口,所有的PO类都应该实现该接口。

我们的实体类目录会分的相对详细些:po(persistant object 持久对象)、qo(query object查询对象)、vo(view object 值对象)、bo(business object 业务对象)。

从该类中可以看出如果你是PO类需要至少三个参数,id:主键、createTime:创建时间 、updateTime:更新时间,之所以将它们三个都抽离因为这在绝大多数的po下都是公用的,如果你想说我的表就是一个日志记录表都没有更新的情况,所以也没有updateTime,这里多加个字段无伤大雅,定义这几个参数好处后面会说下。

BasePO类:

备注

该类是上面PO接口的一个部分实现,如果你懒得定义createTime、updateTime字段可以让你的持久化类直接继承该类即可。

通用接口定义:

解释说明

该接口是本章所讲的核心接口类,看名字可以看出Crud就代表该接口具有增删改查的功能,他的能力也都是继承相对应的具体接口得来。

具体的业务service接口类如果想使用通用service的功能,都应该继承该接口以获得相应方法能力。

使用时需要传递两个泛型值,E: 具体的PO类, PK:PO类的主键类型。

通用增加接口:

通用删除接口:

通用修改接口:

通用查询接口:

通用service的mysql实现:

备注

该类就是实现上面通用服务接口(CrudService),你的具体业务实现类需要继承该类以获得通用的能力。

使用时需注意,使用该类时,注入泛型 E,一定要有对应的 EMapper,例如:使用User的基础服务实现类需要继承MySqlCrudServiceImpl, 前提是要有UserMapper extends CrudMapper 类(这点很重要哈)。

可以看出该实现类也同时维护了createTime、updateTime字段的值,你也就不用管这两个字段的维护了,有的同学可能会有疑问为什么不直接获取mysql的数据库服务上的时间呢,也是很简单的,但是需要注意的是我们的应用服务和mysql数据库服务的时间点通常是不完全一致的(多少会有一些偏差),记录应用服务器的时间也会方便我们后续对线上排查问题时,时间上的一致性。

这里的selectPage方法是我们上一篇文章中给大家留下来的课后思考,从代码中也可以看出PageQO的condition可以接受任意的对象:E、null、Condition、Example或其他的对象(其他对象时会将该对象信息按跟PO类的同名字段拷贝过去进行查询),所以用该selectPage基本上可以满足你对单表分页的所有需求,如果你不太会用通用mapper的Condition和Example类的使用,请自行上网上查查,还是蛮好用的^_^。

如果不理解PageQO、PageVO可以再看一下这篇文章《通用分页》。

成果展示

我们还是以保存用户为例:

用户PO类定义:

用户的Mapper类:

用户的Service类定义:

用户的Service类实现:

备注

这里再次声明,使用UserService的时候一定是已经有了UserMapper extend CrudMapper哈。

备注

本实例我们就叫它demo2了,为了方便后续同学们去查看demo实例的代码。

我们仅仅演示了下插入和分页查看功能,注意分页时我们加入了User userQO参数的传递,来测试下分页功能,当然你可以定义自己的任意查询对象。

添加用户PostMan演示截图:

分页查看用户列表PostMan演示截图:

最后

通用service的第一讲就先到这里啦,不知道对你是否有一些启发呢?如果感觉文章还不错或有些疑问可以关注CSDN账号留言或关注下面的公众号加群等方式来联系我O(∩_∩)O~

附上本实例代码github地址:https://github.com/zhumaer/zhuma/tree/master/zhuma-demo

今日寄语

人的缺点就如同花园里的杂草。杂草不需培植照样生长,所以如果不及时清除,它们很快就会占领整座花园。——拿破仑·希尔

也可以加群哦

都在那等你那!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180201G0ZRX100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券