砍材农夫砍材农夫
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • nodejs
    • npm
    • webpack
    • 微信
    • 正则
    • uniapp
    • app
  • java

    • java基础
    • jdk体系
    • jvm
    • spring
    • spring_cloud
    • spring_boot
    • 分库分表
    • zookeeper
  • python

    • python基础
    • python高级
    • python框架
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • docker
  • k8s
  • devops
  • nginx
  • 元宇宙
  • 区块链
  • 物联网
  • linux
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • nodejs
    • npm
    • webpack
    • 微信
    • 正则
    • uniapp
    • app
  • java

    • java基础
    • jdk体系
    • jvm
    • spring
    • spring_cloud
    • spring_boot
    • 分库分表
    • zookeeper
  • python

    • python基础
    • python高级
    • python框架
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • docker
  • k8s
  • devops
  • nginx
  • 元宇宙
  • 区块链
  • 物联网
  • linux
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • spring-core

    • spring_ioc
    • spring_aop
    • spring三级缓存
  • spring-boot

    • 版本问题
    • 基础问题
    • 特殊场景
  • mybatis-plus

    • MyBatis-Plus常用技巧,助你开发效率翻倍!
  • MyBatis-Plus常用技巧,助你开发效率翻倍!
    • 一、代码生成器:告别重复造轮子
    • 二、条件构造器:复杂查询也能优雅编码
    • 三、自动填充:公共字段不再手动维护
    • 四、批量操作:大数据量场景的救星
    • 五、分页插件:一行代码搞定分页查询
    • 六、防坑指南:这些坑99%的新手都踩过
    • 总结

MyBatis-Plus常用技巧,助你开发效率翻倍!

告别重复SQL,这些技巧让你的DAO层开发事半功倍

在日常开发中,很多同学还在手写基础的增删改查代码,每个Mapper都要写XML、写SQL,重复劳动不说,还容易出错。今天就来聊聊MyBatis-Plus(简称MP)这款神器,看看它如何帮助我们真正解放生产力。

一、代码生成器:告别重复造轮子

这是MP最让人上头的功能之一。通过代码生成器,可以根据数据库表结构,一键生成Entity、Mapper、Service、Controller等各层代码,大幅减少基础编码工作

新版MP推荐使用 FastAutoGenerator,通过链式调用配置数据源、包路径和生成策略即可

FastAutoGenerator.create("jdbc:mysql://localhost:3306/db", "root", "123456")
    .globalConfig(builder -> builder.author("你的名字").outputDir(System.getProperty("user.dir") + "/src/main/java"))
    .packageConfig(builder -> builder.parent("com.example.project"))
    .strategyConfig(builder -> builder.addInclude("user", "order"))
    .execute();

使用代码生成器后,合理配置可减少约 70% 的基础代码编写量。不过需要提醒的是:生成的代码只是骨架,业务逻辑还是要自己动手哦。

二、条件构造器:复杂查询也能优雅编码

条件构造器是MP的灵魂所在,支持用面向对象的方式构建SQL条件,彻底告别手动拼接SQL的噩梦。

推荐优先使用 LambdaQueryWrapper,因为它通过方法引用来引用字段(如 User::getName),可以享受编译期检查的优势:

// ✅ 推荐:编译期检查字段有效性
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
       .gt(User::getAge, 18)
       .like(User::getEmail, "example.com")
       .orderByDesc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);

如果手头已经是QueryWrapper的代码也没关系,后续可以平滑迁移到Lambda版本,不需要改动业务逻辑。

三、自动填充:公共字段不再手动维护

在开发中,我们经常要维护 create_time、update_time、create_by、update_by 这类公共字段。MP的自动填充功能能自动处理这些字段,极大简化开发过程。

使用步骤超简单:

第一步:在实体类字段上添加 @TableField 注解:

@TableField(fill = FieldFill.INSERT)
private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

第二步:实现 MetaObjectHandler 接口:

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }
    
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

现在新增和更新时,这些字段就会自动填充啦,再也不用手动set了!

四、批量操作:大数据量场景的救星

在处理数据迁移、批量导入等场景时,逐条插入性能极差。MP的批量操作可以显著提升数据处理效率。

IService 提供了 saveBatch、updateBatchById 等方法,使用很方便:

// 批量新增,默认批次大小1000
userService.saveBatch(userList, 500);

但有个重要优化:MP的 saveBatch 方法内部实际上是循环单条插入再批量刷新。要获得真正的批量插入性能提升,需要在数据库连接URL中开启 rewriteBatchedStatements=true:

spring.datasource.url=jdbc:mysql://localhost:3306/db?rewriteBatchedStatements=true

开启后,多条INSERT语句会被合并为一条执行,性能大幅提升,某些场景下甚至能提升25倍以上。

五、分页插件:一行代码搞定分页查询

分页查询是每个项目的标配功能。MP的分页插件基于MyBatis物理分页,支持MySQL、Oracle等多种数据库。

首先注册分页插件:

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

然后在业务代码中直接调用:

Page<User> page = new Page<>(1, 10);
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getStatus, 1);
Page<User> result = userMapper.selectPage(page, wrapper);
// 结果自动封装到Page对象中,包含records、total、pages等

六、防坑指南:这些坑99%的新手都踩过

1. 不要同时引入MyBatis和MyBatis-Plus的依赖

MP的starter已包含MyBatis核心包,同时引入会导致冲突。

2. 小心全表扫描

当 selectList 的 wrapper 参数为null时,会执行全表扫描,在大数据量下后果很严重。

3. 自动填充有默认策略

MetaObjectHandler 提供的默认方法策略是:如果属性已经有值则不会覆盖,如果填充值为null则不填充。这一点需要注意,避免预期与实际不符。

4. 批量操作的事务管理

批量操作默认不开启事务,需要手动管理以确保数据一致性。

5. 主键策略的选择

使用 @TableId 注解时,推荐使用 IdType.AUTO(数据库自增)或 IdType.ASSIGN_ID(雪花算法),避免使用 INPUT 导致忘记手动赋值。

总结

MyBatis-Plus通过无侵入的增强设计,在不改变现有代码结构的基础上,让DAO层开发效率大幅提升。

今天分享的这些技巧涵盖了代码生成、条件查询、字段填充、批量操作和分页查询等常用场景,掌握它们可以帮助你:

  • 减少 70% 以上的重复代码编写
  • 消除SQL拼接带来的隐患
  • 提升批量数据处理性能
  • 让团队编码更加规范和统一

如果你还没有在项目中使用MP,不妨从今天开始尝试。如果你已经在用,欢迎在评论区分享你的使用心得!

最近更新: 2026/4/3 09:48
Contributors: kcnf