java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot集成MyBatis-Plus

SpringBoot4集成MyBatis-Plus实现单表操作零SQL的实践教学

作者:gis开发之家

MyBatis-Plus是国内主流持久层方案,在MyBatis基础上增强了单表零SQL与SQL可控性,本文介绍了Spring Boot整合MP依赖、配置、BaseMapper内置17种方法、LambdaQueryWrapper条件构造器、分页插件、逻辑删除、代码生成器等企业级要点,希望对大家有所帮助

国内互联网项目最主流的持久层方案不是 JPA,而是 MyBatis‑Plus——既保留 SQL 可控性,又提供单表零 SQL 的极致效率。本文将手把手带你整合 MP、玩转条件构造器、代码生成器、分页插件与逻辑删除,直接对标企业级开发。

一、MyBatis‑Plus 是什么?和 JPA / MyBatis 比啥区别?

定位一句话

MyBatis‑Plus = MyBatis + 通用 Mapper + 条件构造器 + 代码生成 + 分页/逻辑删除开箱即用

不替换 MyBatis,只是在上面加了一层"增强",所以原生 XML 照样能用。

三者对比

方案SQL 可控性单表 CRUD 成本复杂 SQL国内流行度
MyBatis 原生⭐⭐⭐⭐⭐手写 XML,成本高⭐⭐⭐⭐⭐高
Spring Data JPA⭐⭐(自动生成)几乎零代码⭐⭐(复杂 JPQL 难写)中
MyBatis‑Plus​⭐⭐⭐⭐⭐零 SQL(BaseMapper)​⭐⭐⭐⭐⭐(XML 随时补)最高​

选型建议:

二、Spring Boot 4 整合 MyBatis‑Plus

引入依赖

<dependencies>
    <!-- Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MyBatis-Plus(适配 Spring Boot 4 / Spring 6) -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!-- MySQL 驱动 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- Druid 连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-3-starter</artifactId>
        <version>1.2.23</version>
    </dependency>
    <!-- Lombok(可选,简化实体) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

注意:Spring Boot 4 必须选 mybatis-plus-spring-boot3-starter,不要用老版 mybatis-plus-boot-starter。

基础配置(application.yml)

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: root
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true   # 下划线转驼峰
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印 SQL(开发用)
  global-config:
    db-config:
      id-type: auto                     # 主键自增
      logic-delete-field: deleted       # 逻辑删除字段名
      logic-delete-value: 1
      logic-not-delete-value: 0
  mapper-locations: classpath*:mapper/*.xml   # 如需手写 XML

启动类加扫描

@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

三、实体与 Mapper(零 SQL 核心)

实体类(@TableName / @TableId / @TableField)

@Data
@TableName("t_user")
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;

    @TableField("username")
    private String username;

    private String email;

    private Integer age;

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

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

    @TableLogic   // 逻辑删除
    private Integer deleted;
}

核心注解速查:

注解作用
@TableName表名映射
@TableId主键(IdType.AUTO / ASSIGN_ID / UUID)
@TableField字段映射 / 自动填充
@TableLogic逻辑删除标记
@Version乐观锁字段

Mapper 接口(就这么一行)

public interface UserMapper extends BaseMapper<User> {
}

BaseMapper 已内置 17 个方法:

insert / insertBatchSomeColumn
deleteById / deleteByMap / delete / deleteBatchIds
updateById / update
selectById / selectBatchIds / selectByMap / selectOne / selectList / selectCount
selectPage / selectMaps / selectObjs

不用写任何 XML,单表全搞定。

直接开用

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User create(User user) {
        userMapper.insert(user);
        return user;
    }

    public User getById(Long id) {
        return userMapper.selectById(id);
    }

    public List<User> listAll() {
        return userMapper.selectList(null);
    }

    public void delete(Long id) {
        userMapper.deleteById(id);  // 逻辑删除(配置了 @TableLogic)
    }
}

四、条件构造器(QueryWrapper / LambdaQueryWrapper)

QueryWrapper(字段名字符串)

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18)
       .like("username", "zhang")
       .orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);

LambdaQueryWrapper(推荐,防字段名写错)

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 18)
       .like(User::getUsername, "zhang")
       .between(User::getCreateTime, start, end)
       .orderByDesc(User::getCreateTime);

List<User> list = userMapper.selectList(wrapper);

编译期校验字段名,重构安全,强烈推荐

常用条件方法速查

方法SQL 片段
.eq(col, val)=
.ne(col, val)!=
.gt / ge / lt / le> >= < <=
.like / notLikeLIKE %x%
.likeLeft / likeRight%x / x%
.in(col, list)IN (...)
.between(col, a, b)BETWEEN a AND b
.isNull / isNotNullIS NULL / IS NOT NULL
.orderByAsc / DescORDER BY
.last("LIMIT 1")拼接原生片段(慎用)

UpdateWrapper 更新

LambdaUpdateWrapper<User> update = new LambdaUpdateWrapper<>();
update.eq(User::getId, 1L)
      .set(User::getAge, 20)
      .set(User::getEmail, "new@test.com");

userMapper.update(null, update);

五、分页插件(必须配置,否则分页失效)

配置类

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件(指定数据库类型)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 防止全表更新
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        return interceptor;
    }
}

使用分页

public Page<User> pageUsers(int current, int size, Integer minAge) {
    Page<User> page = new Page<>(current, size);

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.ge(minAge != null, User::getAge, minAge)
           .orderByDesc(User::getCreateTime);

    return userMapper.selectPage(page, wrapper);
}

返回结构:

{
  "records": [...],
  "total": 128,
  "size": 10,
  "current": 1,
  "pages": 13
}

六、自动填充(createTime / updateTime)

实现 MetaObjectHandler

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }
}

配合实体上 @TableField(fill = ...) 自动生效

七、代码生成器(企业级提效神器)

引入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.7</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.33</version>
</dependency>

生成脚本(一次性运行)

public class CodeGenerator {
    public static void main(String[] args) {
        FastAutoGenerator.create(
                "jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=Asia/Shanghai",
                "root", "root")
            .globalConfig(builder -> builder
                .author("yourname")
                .outputDir(System.getProperty("user.dir") + "/src/main/java")
                .commentDate("yyyy-MM-dd")
                .enableSwagger())
            .packageConfig(builder -> builder
                .parent("com.example.demo")
                .entity("domain")
                .mapper("mapper")
                .service("service")
                .controller("controller")
                .mapperXml("mapper"))
            .strategyConfig(builder -> builder
                .entityBuilder()
                    .enableLombok()
                    .logicDeleteColumnName("deleted")
                    .versionColumnName("version")
                .controllerBuilder()
                    .enableRestStyle()
                .mapperBuilder()
                    .enableMapperAnnotation()
                    .enableBaseResultMap())
            .templateEngine(new FreemarkerTemplateEngine())
            .execute();
    }
}

一键生成 Entity + Mapper + Service + Controller + XML

八、逻辑删除 & 乐观锁(生产必配)

逻辑删除

实体字段:

@TableLogic
private Integer deleted;

调用 deleteById() 实际执行:

UPDATE t_user SET deleted = 1 WHERE id = ? AND deleted = 0

查询自动追加:

SELECT * FROM t_user WHERE deleted = 0

乐观锁(@Version)

实体:

@Version
private Integer version;

更新时自动:

UPDATE t_user SET ..., version = version + 1 WHERE id = ? AND version = ?

并发冲突抛 OptimisticLockException,可捕获重试。

九、Spring Boot 4 新变化 & 兼容性

十、常见坑位总结

坑1:分页不生效,全表查询

没加 MybatisPlusInterceptor + PaginationInnerInterceptor

坑2:字段名不匹配(驼峰 vs 下划线)

开启 map-underscore-to-camel-case: true,或显式 @TableField

坑3:逻辑删除不生效

检查 @TableLogic + 全局 logic-delete-field 冲突(二选一即可)

坑4:ResultMap 报 Unknown Column

用代码生成器统一字段,避免手敲 XML 错位

坑5:MP 和 JPA Starter 同时引入冲突

二选一,不要都加

十一、本篇总结

  1. Spring Boot 4 用 mybatis-plus-spring-boot3-starter
  2. BaseMapper<T> 提供单表零 SQL 的 17 个方法
  3. 条件构造器用 LambdaQueryWrapper,类型安全
  4. 分页 / 乐观锁 / 防全表更新都靠 MybatisPlusInterceptor
  5. 代码生成器一次性产出整套 CRUD,效率拉满

到此这篇关于SpringBoot4集成MyBatis-Plus实现单表操作零SQL的实践教学的文章就介绍到这了,更多相关SpringBoot集成MyBatis-Plus内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文