mybatis-plus
mybatis-plus copied to clipboard
关于改进 IService 和 ServiceImpl 的建议
当前使用版本(必填,否则不予处理)
3.5.4.1
该问题是如何引起的?(确定最新版也有问题再提!!!)
非问题。建议。
重现步骤(如果有就写完整)
N/A
报错信息
N/A
==========================
本来想建议直接去掉 IService 和 ServiceImpl,但考虑到有代码生成器和各种依赖,再加上国内做项目多数还是短平快,很多人不在乎领域设计,所以觉得还是做加法比较合适。
之所以有这个想法是基于如下两个观察:
- Mybatis-Plus 说到底还是Dao工具,而 IService 这个名字上溢了,不符合最佳实践(客观上鼓励了将 Dao 层当 Service 层)。它实际上的定位应该是 Repository。建议将 IService 改名为 IRepository,ServiceImpl 改名为 RepositoryImpl。
- 用户要想用这个接口时,需要先让自己的接口继承 IRepository,然后让实现类继承 RepositoryImpl 再实现用户接口。但随着面向领域设计概念的渐渐推开,许多用户不愿意让自己的接口依赖外部框架(即使中间加一层 BaseService)。根据DDD的概念,Repository接口是很重要的组件,它是划分领域模型与infra(细节)的界面:Service的实现属于领域模型,而Repository的实现属于infra(细节);Repository接口是二者共同依赖的抽象,是属于领域模型的;因此必然不想依赖外部框架。那么,用户Repository接口不继承IRepository,只让实现类继承 RepositoryImpl 可不可以呢?可以,只要自己定义个接口就可以(一般情况下,方法是 IRepository 的一个子集就够用了)。但此时实现类却无法直接利用很多方法,如getById。原因是getById是 IRepository 的一个默认方法。一个接口的默认方法不属于实现类,也就不能变成用户自定义接口的实现。用户得在实现类里重复实现一遍getById。因此建议将 IRepository 里的默认方法全部搬到 RepositoryImpl 里实现,IRepository变为老式纯接口。另外,RepositoryImpl 其实应该改叫 RepositorySupport,还原它实用工具的本质。
这样,我们获得了如下好处:
- 不会误导小朋友混淆Service层和Dao层,鼓励大家定义自己的业务接口。
- 完全不在乎的人可照旧用 IService 和 ServiceImpl。
- 想用DDD,但没有洁癖的同学可以改用 IRepository,并沿用已有的继承模式,即 MyRepository extends IRepository;MyRepositoryImpl extends RepositorySupport implements MyRepository。
- 有DDD洁癖的同学可定义自己的 Repository 接口,只利用 RepositorySupport 提供的实现。一些常用方法只要定义的和 IRepository 里的一样就能被 RepositorySupport 接住,最少化手写代码。
综上所述,建议: 1)新增 IRepository;与 IService 相同 2)新增 RepositorySupport;与 ServiceImpl 相同。 3)将原 IService 里的default方法搬到 RepositorySupport 里去实现; 4)为了向前兼容,IService、ServiceImpl 予以保留,加说明性文字。
附上参考实现(很简单) extension(mybatisplus repository).zip
支持呦 这两个东东已经成为知乎或者脉脉上打击mp的主攻点了
在DDD设计的时候,确实会有这个担忧,对于那些有洁癖的同学现阶段的mp设计的ISevice和ServiceImpl有一些歧义,正如你所提到的有些刚开始接触web开发的人员他们的关注点不是在框架本身
确实, IService 和 ServiceImpl把Dao和Serivce的关系模糊化了,我见过很多直接懒得继承方法而把业务逻辑直接写在了controller里,service久而久之就成为了名副其实的dao了
Repository 从名称上来看确实比 Service 好很多,支持
感谢反馈当初设计上 IService 其实就是 IRepository 的等效功能,命名上可能是困惑,该问题后续会考虑您的建议调整
赶紧行动吧!:D 这个change不复杂。好处是实实在在的,会有更多的人愿意采用mp,也免得别人拿这攻击mp。
还需要解决的这个问题,使用IService的批量方法,事务有问题
可是,如果service 改为repository ,那mapper 属于哪一层呢? jpa中最后一层叫repository,上面是service, 而mybatis 最后一层是mapper,上一层是service,我感觉比较对应
可是,如果service 改为repository ,那mapper 属于哪一层呢? jpa中最后一层叫repository,上面是service, 而mybatis 最后一层是mapper,上一层是service,我感觉比较对应
你这个思路就不对,有没有一种可能,mp的mapper其实也对应于jpa的repository,只不过mapper提供低级访问,repository提供高级访问,至于service应该是开发者自己实现的业务层,根本不应该出现在一个基础库里。
可是,如果service 改为repository ,那mapper 属于哪一层呢? jpa中最后一层叫repository,上面是service, 而mybatis 最后一层是mapper,上一层是service,我感觉比较对应
这个跟框架没有关系,怎么叫都是对应那一层
我们的DDD实现里目前是完全抛弃了IService的,确实不太适用,只用到了BaseMapper
我们的DDD实现里目前是完全抛弃了IService的,确实不太适用,只用到了BaseMapper
其实把IService中的方法合并到BaseMapper多好,还丰富了BaseMapper的功能,而且剔除了IService这个奇怪的东东。一举两得。
确实有问题,很多不懂的人拿起来都用,我接手的一个框架,有人这样用,搞的自定义缓存都不好加,对于高手可以区分开,对于不懂的人意识不到这样搞的坏处,删除这两个最好。
IService本身应该起到工具的作用,如果按照DDD严格来区分,只需要在Mapper中继承BaseMapper就可以了,Service类自己实现业务代码不继承ServiceImpl和IService,自己的业务去调用Mapper的实现类方法就行。
但是这个还得看业务的体量,业务不是很复杂的情况下,可以梭哈写在一起,倒也无所谓,这更多的是一个设计模式和开发思想
IService本身应该起到工具的作用,如果按照DDD严格来区分,只需要在Mapper中继承BaseMapper就可以了,Service类自己实现业务代码不继承ServiceImpl和IService,自己的业务去调用Mapper的实现类方法就行。
但是这个还得看业务的体量,业务不是很复杂的情况下,可以梭哈写在一起,倒也无所谓,这更多的是一个设计模式和开发思想
嗯。正确的用法是只用BaseMapper的增改删三种类型方法,其他的走xml进行查询和权限过滤。
确实,在DDD领域中IService显得不伦不类,初次学习,我就把他当Service来用了,但学过了DDD,发现确实有问题。 其实极端一点,直接改名,不考虑兼容性,强制纠正这一问题
3.5.7 开始mapper合并service能力
已发布3.5.7-SNAPSHOT 目前已有BaseMapper新增能力: 1.saveBatch 批量保存 2.updateBatchById 批量更新 3.saveOrUpdateBatch and saveOrUpdateBatch(自定义条件) 批量保存或更新 4.saveOrUpdate 保存或更新 5.deleteById,deleteBatchIds默认支持逻辑删除填充,增加重载方法参数是否需要填充处理.
后续规划,删除service层,只保留mapper,不再增加多层操作.
待定项: 1.批量操作是否需要控制批次大小
已发布3.5.7-SNAPSHOT 目前已有BaseMapper新增能力: 1.saveBatch 批量保存 2.updateBatchById 批量更新 3.saveOrUpdateBatch and saveOrUpdateBatch(自定义条件) 批量保存或更新 4.saveOrUpdate 保存或更新 5.deleteById,deleteBatchIds默认支持逻辑删除填充,增加重载方法参数是否需要填充处理.
是不是可以把表关联查询的方法也加进来?我看原计划是4.0加的,结果4.0鸽了
已发布3.5.7-SNAPSHOT 目前已有BaseMapper新增能力: 1.saveBatch 批量保存 2.updateBatchById 批量更新 3.saveOrUpdateBatch and saveOrUpdateBatch(自定义条件) 批量保存或更新 4.saveOrUpdate 保存或更新 5.deleteById,deleteBatchIds默认支持逻辑删除填充,增加重载方法参数是否需要填充处理.
是不是可以把表关联查询的方法也加进来?我看原计划是4.0加的,结果4.0鸽了
mybatis本来就支持的功能为什么还要去造轮子
已发布3.5.7-SNAPSHOT 目前已有BaseMapper新增能力: 1.saveBatch 批量保存 2.updateBatchById 批量更新 3.saveOrUpdateBatch and saveOrUpdateBatch(自定义条件) 批量保存或更新 4.saveOrUpdate 保存或更新 5.deleteById,deleteBatchIds默认支持逻辑删除填充,增加重载方法参数是否需要填充处理.
是不是可以把表关联查询的方法也加进来?我看原计划是4.0加的,结果4.0鸽了
mybatis本来就支持的功能为什么还要去造轮子
建议看看 mybatis-plus-join,理论上有这个库后 mybatis-plus 不需要做联表功能了,能不用 mybatis 来写 sql 语句是最好的。
已发布3.5.7-SNAPSHOT 目前已有BaseMapper新增能力: 1.saveBatch 批量保存 2.updateBatchById 批量更新 3.saveOrUpdateBatch and saveOrUpdateBatch(自定义条件) 批量保存或更新 4.saveOrUpdate 保存或更新 5.deleteById,deleteBatchIds默认支持逻辑删除填充,增加重载方法参数是否需要填充处理.
是不是可以把表关联查询的方法也加进来?我看原计划是4.0加的,结果4.0鸽了
mybatis本来就支持的功能为什么还要去造轮子
建议看看 mybatis-plus-join,理论上有这个库后 mybatis-plus 不需要做联表功能了,能不用 mybatis 来写 sql 语句是最好的。
建议优先看看官方的,https://github.com/mybatis/mybatis-dynamic-sql
建议优先看看官方的,https://github.com/mybatis/mybatis-dynamic-sql
mybatis官方的体验欠佳。mybatis-plus-join只需要在mybatis-plus基础上把BaseMapper换成MPJBaseMapper就能支持联表,表达式写起来也很自然。
建议优先看看官方的,https://github.com/mybatis/mybatis-dynamic-sql
mybatis官方的体验欠佳。mybatis-plus-join只需要在mybatis-plus基础上把BaseMapper换成MPJBaseMapper就能支持联表,表达式写起来也很自然。
个人觉得mp的主要任务是支持mybatis官方框架,拓展增强基础能力,而不是套壳一些其他的三方插件当自己功能
而不是套壳一些其他的三方插件当自己功能
歪曲我的观点没意思,我说之前的是:
建议看看 mybatis-plus-join,理论上有这个库后 mybatis-plus 不需要做联表功能了
既然都用mybatis-plus了,那更应该利用好它繁荣的生态,通过拓展库来无缝集成新功能。特别是:项目已经大量使用mybatis-plus lambda查询的情况下。
这样mybatis-plus就不需要再去造联表查询轮子,保持精简,毕竟你也说了有dynamic sql,再不济还能直接写sql。
否则还不如把mybatis-plus从项目dependencies里删了,只用mybatis和官方配套的dynamic sql。
我还是想不通你为何会爆出这么神奇的言论,难道mybatis-plus开发团队,或者你干过这种事情?
而不是套壳一些其他的三方插件当自己功能
歪曲我的观点没意思,我说之前的是:
建议看看 mybatis-plus-join,理论上有这个库后 mybatis-plus 不需要做联表功能了
既然都用mybatis-plus了,那更应该利用好它繁荣的生态,通过拓展库来无缝集成新功能。特别是:项目已经大量使用mybatis-plus lambda查询的情况下。
这样mybatis-plus就不需要再去造联表查询轮子,保持精简,毕竟你也说了有dynamic sql,再不济还能直接写sql。
否则还不如把mybatis-plus从项目dependencies里删了,只用mybatis和官方配套的dynamic sql。
我还是想不通你为何会爆出这么神奇的言论,难道mybatis-plus开发团队,或者你干过这种事情?
1.理论上有这个库指的不是mp理论上有这个库?那不就是套壳?
2.我看到mp现有功能都是基于基础框架自己做实现的,根本不会去集成一些不知名小众且可能随时停更断维护的类库。
3.而且我觉得你应该就是论事!什么叫做神奇的言论?多神奇啊?还我或官方干过这事,我还觉得你干过呢