mybatis-plus 我不用了

本文探讨了MyBatis Plus在项目中的实际应用效果,包括其优点如一键生成代码、内置分页支持等,同时也揭示了其在代码量、性能、并发处理和维护成本上存在的潜在问题。
部署运行你感兴趣的模型镜像

优点

  1. 一键生成controller/service/mapper/entity/xml
  2. 提供通用针对单表的增查删改
  3. 提供Wrapper 针对相对复杂及自定义的查询操作
  4. 内置多种数据库的分页查询支持
  5. ID主键生成器
  6. 全局逻辑锁
  7. 还有其他缓存/批量处理的能力

从这里看功能还是相当完美,很吸引人。不过只从项目中引入了该mybatis增强plus后,发现代码量变多了,性能下降了,维护成本变高了,对开发人员的要求更高了

比如:

想实现单条查询,有现成的为什么不用之查询如下:

		public T getById(Serializable id)  单条语句查询

面试必考问题:select * 问题,要解决这个问题,可以使用wrapper:

        QueryWrapper wrapper = new QueryWrapper(new LoginUserInfo());
        wrapper.select("id","name","sex").eq("id",1);
        getBaseMapper().selectOne(wrapper);

而SQL:

		select id,name,sex from user_info where id=1;

一条SQL语句它不香吗,plus要么查询所有字段浪费性能,要么代码量大,增加维护成本

再比如:

想更新某字段,有现成的为什么不用之写法:

        Use user = getBaseMapper().selectById(1);
        user.setName("hello");
        getBaseMapper().updateById(user);

使用了plus的同学很多人是否都写过这样的代码,当需要修改某个值时,整条记录全字段取出,修改其中某个值,再更新回去。因为plus提供了这样的get和update方法,很自然使用这种方式更新数据。
坑:

  1. 后来业务需要增加了一个lastVisitTime(最后访问时间字段)并发情况下,使用上面的方式,一个线程更新name,一个线程更新lastVisitTime。game over,值不能等于预期.做更新lastVisitTime新需求的同学,可能会发生我明明更新了,为啥值还是原来的值。成功埋下一个“非必现”问题

再比如:

想实现简单表关联查询,有现成的为什么不用之想实现类SQL功能如下:

SELECT name,phone from user where id in (select user_id from customer where appId=1 )

因为有plus,还有java8的lambda,可能会写成这样:

        QueryWrapper<Customer> wrapper = new QueryWrapper();
        wrapper.eq("appId",1);
        List<String> ids = getBaseMapper().selectList(wrapper)
        .stream().map(Customer::getUserId).collect(Collectors.toCollection());
        
        userService.listByIds(ids);

这里不仅和数据库交互两次,而且如果其中有个字段很长,比如"文章内容"等字段(现在没有谁知道以后有没有,需求天天变)极限情况下会有不下于10倍的性能差距,浪费系统资源和内存,也增加了代码量。也增加了排查问题的难度

再比如:

流水幂等性存储问题时,看到plus有以下方法,有现成的为什么不用之通过ID去重:

public boolean saveOrUpdate(T entity) 

看一下它的其中一行实现:

    return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity);

由方法:getById((Serializable) idVal),save(entity),updateById(entity) get一次表字段全量来判断是否为空,再选择更新或者保存。
换成SQL:

INSERT IGNORE INTO  record(id,name,time) values(1,'大壮', '2020-03-08'); 
INSERT INTO record(id,name,time) VALUES (1,'大壮', '2020-03-08') ON DUPLICATE KEY 
UPDATE name='大壮',time='2020-03-08';

单条更新可能没什么感觉,看看批量处理,入库一万条,多一万条全字段查询:

public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) 

项目初期,我们爱jpa,爱mybatis-plus因为它能有简单的增查删改,能快速的完成项目初期的大部份功能,快速上线,而且项目初期没什么数据,对内存,对数据库操作都没啥要求。后来,产品的需求越来越变态,对项目有性能有要求的时候,jpa和plus对开发人员的要求就高了,都能用,用不用得好就是另一回事了。在团队协作开发的时候,开发人员之间肯定都会优先考虑现有的,封装好的接口来实现快速开发。封装好的功能是好用,但对后期升级维护,问题排查,性能提升这才是问题

plus的定位为不修改原有mybatis逻辑的增强。但如果走极简编程的话,mybatis就够了,我要plus来干嘛,项目越大,集成了plus越重,性能影响越大

MybatisCodeHelperPro插件

您可能感兴趣的与本文相关的镜像

Seed-Coder-8B-Base

Seed-Coder-8B-Base

文本生成
Seed-Coder

Seed-Coder是一个功能强大、透明、参数高效的 8B 级开源代码模型系列,包括基础变体、指导变体和推理变体,由字节团队开源

评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值