mybatisPlus-mapper的注入值得思考

1. 前言

mybatisPlus-mapper好用,好用到感觉自己不会写sql了(哈哈)!!!!本人接触mybatisPlus-mapper一年半(用的比较多的是mybatis),所以一直对xxxMapper面向编程的sql编写这种玩法,随心所欲的写法很感兴趣(牛逼plus)。

但在整理迁移食品方案场景层代码yingzi-scene-frdscheme过程中,发现了一些典型代码编写问题,特别是xxxMapper随意注入问题,关系错乱复杂扯不清理不清,这个问题滥用程度触目惊心,大家可能没啥很大的意识,毕竟mybatisPlus的xxxMapper简直所向无敌,面向编程的sql编写,让后来者为之跪拜,爽啊爽(如果用过jpa那种通过方法反射sql生成的,那种方式方法简直惨不忍睹只想骂人,getUserNameAndPassWordAndStatusAndXXXX 想哭),但就是这么个简单问题,其实有很多地方值得我们思考。

思考之前,我们简单回顾下类与类之间的关系(此处简单写的,具体uml可以百度)

类与类之间的关系
横向关系
① 依赖关系:某个对象在执行指定方法时需要其他类的对象参与完成;
②关联关系:它体现的是两个类,或者是类与接口之间的语义级别一种强依赖关系;
③ 聚合关系:是一种特殊的关联关系, 代表 整体与部分,整体和局部可以独立存在,has a关系;
④ 组合关系:组合,称为强聚合,整体与局部的生命周期相同,不能脱离关系, is a 关系;
纵向关系
①继承关系;
②实现关系;
 

2. 分析

纵向关系在设计模式上多去考虑

我来一一分析目前横向关系 (以下都是记忆目前现状分析)

2.1. 依赖关系&&关联关系 弱依赖

 

MicrowaveSchemeAppService和FoodManagementAppService的关系-》化成实体就是微波炉方案(microwave_scheme)和食物(food_management)关系

我们从业务场景分析下两者的关系,在产生微波炉方案的时候,需要先选择食物,选完食物后,就可以去设置微波炉方案了,后续就可以独立对设置微波炉方案和食品管理各种操作了(这里的食物来自哪里对方案来说毫无意义,同时方案变成啥样也对食品本身这个实体不造成任何冲击),所以我们简单的分析他们两者算一个简单的关联关系。如上图,微波炉方案和食物两个实体都有各自独立的操作和发展路线(有独自的controller和service),只是在微波炉方案设置的时候引入了食物id。

那回归到代码如果我们有1个方法【查询方案且需要回填食物名称】,就如上图一样MicrowaveSchemeAppService依赖食物我们注入哪个呢foodmanagementMapper??or foodManagementAppService??,下面哪个是对的

(两个方法模式,有哪个像自己)

方法1:注入foodmanagementMapper

 @Override

    public MicrowaveSchemeResDto selectOne(Long id) {

        MicrowaveSchemePo po = microwaveschemePoService.getById(id);

        MicrowaveSchemeResDto resDto = MicrowaveSchemeAssembler.convertPo2ResDto(po);

        if (resDto != null) {

            //填充食品管理数据

            FoodManagementPo FoodManagementPo = foodmanagementMapper.selectOne(wrapper);

方法2:注入foodManagementAppService

 @Override

    public MicrowaveSchemeResDto selectOne(Long id) {

        MicrowaveSchemePo po = microwaveschemePoService.getById(id);

        MicrowaveSchemeResDto resDto = MicrowaveSchemeAssembler.convertPo2ResDto(po);

        if (resDto != null) {

            //填充食品管理数据

            FoodManagementResDto foodManagementResDto = foodManagementAppService.selectOne(resDto.getFoodManagementId());

在不经意间,大家可能会写方法1:注入foodmanagementMapper,毕竟myplus的xxxMapper简直所向无敌,但是他真的对吗,微波炉方案这个实体对象真的需要关心食物这个实体那么多信息吗,甚至都赤裸裸的得知道他的数据源jdbc(xxxMapper本质上就是写sql),可能还是有人不觉得,这有什么的,那我再说下业务,我们在食品研发系统上线后,后面又来了个食品味道商业研究,需要独立一个场景,共用食品实体,将食品实体抽到公共层,如果是这样做的话,你还会采用方法1吗??当你想移走食品时,发现MicrowaveSchemeAppService竟然写了食品的sql语句(mapper本质就是sql),简直了哈哈。

方法2:注入foodManagementAppService好处再于,微波炉方案对食物这个实体关心的东西很少,提供了接口,具体怎么实现,数据来源是本地库还是其他场景层甚至文件和微波炉方案无关,这样改造是不是很简单呢?

说了那么多,大家回过头再分析分析我下面截图的这几个mapper注入,往前思考,这么注入是不是蛋疼。。。。。。。。

 

 

2.2. 组合关系 强聚合  is a 关系

整体与局部的生命周期相同,不能脱离关系,其实从DDD模型考虑,就是实体和值对象问题,聚合根的问题,很典型的场景就是订单和订单明细,如下图

 

订单是实体,订单的明细是值对象,订单和订单明细是一个整体,service完全应该是一个聚合根,service应该注入订单Mapper和订单明细Mapper,不应该单独出现订单和订单明细对应的controller和service方法,这里有时得吐槽代码生成工具,一股脑的生成。这些controller或者service代码的接口永远是订单和订单明细是一个整体,作为一个事物统一入口,不存在出现只操作订单或者只操作明细的独立入口。

那为什么要这么考虑呢,订单service聚合根注入订单Mapper和订单明细Mapper,其实仔细想一想,如果只考虑当前,其实上文也说得,两个类是is a 关系,同一个生命周期,用一个service控制更方便掌控,如果考虑长远一点,这种事实表,以后数据量大了,你想分库分表什么的,这么设计,你的代码改动微乎其微,因为同一个生命周期的东西,无论如何拆分他们都是要一起走的。

2.3. 聚合关系  不是很强聚合 has a 关系

是一种特殊的关联关系, 代表 整体与部分,整体和局部可以独立存在,has a关系;很典型的就是健康场景的用户和用户口味关系。从原型prd设计上,初版的用户和用户口味是强绑定的(修改用户基本信息,里面包含了用户口味),但是后期影子app使用看,用户和用户口味发展成了两个界面,这种就很符合这种可以看成一个整体,但是又可以局部操作。

回归代码上,可以开发成3个controller,3个service,3个mapper,如下图。

 

这里可能会有疑问为啥要多加个用户&&口味复合service接口,其实很明显,符合单一职责原则,或者从DDD领域模型分析,这个类更像一个聚合服务,如果前端同时传入用户&&用户口味一个接口,那么聚合服务负责拆分处理分别调用各自的service服务即可

3. 总结

说得那么多,时间多,谁不想多在代码上下功夫,毕竟业务驱动下,能跑起来的代码就是好代码。当然也还是有人反驳,现在微服务统一天下之势,高举着每个微服务都是高内聚低耦合,一个服务场景下的数据库我想怎么写就怎么写,想怎么注入就怎么注入,那引入一句话

  程序员千万不要重写代码,会带来灾难性的毁灭

结束本文!!!!!!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值