一、介绍MyBatis-Plus:

1.概念

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

MyBatis-Plus的官网简介:https://baomidou.com/introduce/

2.特点:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

3.框架结构:

二、配置MyBatis-Plus:

1.引入依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.15</version>
</dependency>

2.使用 @MapperScan 注解扫描 mapper 文件:

@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3.在 application.yml 文件中增加MyBatis-Plus 的统一配置:

# mybatis 相关统一配置
mybatis-plus:
  configuration:
    #开启下划线转驼峰
    map-underscore-to-camel-case: true

作用:将数据库表中的下划线命名方式映射为 Java 对象中的驼峰命名方式。例如,数据库表中的列名为 user_name,对应的 Java 对象的属性名为 userName。

三、基本使用

1. BaseMapper CRUD

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

// Mapper 接口 —— 继承 BaseMapper 即拥有全套单表 CRUD
public interface UserMapper extends BaseMapper<User> {}
User user = new User();
user.setName("张三");
user.setAge(25);
userMapper.insert(user);  // id 自动回填到实体
userMapper.deleteById(1L);
userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L));

// 条件删除
userMapper.delete(new LambdaQueryWrapper<User>()
    .lt(User::getAge, 18)
    .eq(User::getName, "张三")
);
// 只更新非 null 字段
User user = new User();
user.setId(1L);
user.setName("李四");
userMapper.updateById(user);

// 条件更新
userMapper.update(user, new LambdaUpdateWrapper<User>()
    .eq(User::getAge, 25)
);
User user = userMapper.selectById(1L);
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L));

List<User> users = userMapper.selectList(
    new LambdaQueryWrapper<User>()
        .eq(User::getAge, 25)
        .orderByDesc(User::getCreateTime)
);

Long count = userMapper.selectCount(
    new LambdaQueryWrapper<User>().gt(User::getAge, 20)
);

2. 条件构造器 Wrapper

LambdaQueryWrapper
// SELECT * FROM user WHERE age BETWEEN 20 AND 30
//   AND name LIKE '%张%' AND email IS NOT NULL
//   ORDER BY age DESC, id ASC LIMIT 10

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
    .between(User::getAge, 20, 30)
    .like(User::getName, "张")
    .isNotNull(User::getEmail)
    .orderByDesc(User::getAge)
    .orderByAsc(User::getId)
    .last("LIMIT 10");

List<User> users = userMapper.selectList(wrapper);
条件方法速查
方法 说明 SQL
eq 等于 name = '张三'
ne 不等于 name <> '张三'
gt / ge 大于 / ≥ age > 18
lt / le 小于 / ≤ age < 30
between 区间 age BETWEEN 20 AND 30
like / notLike 模糊 name LIKE '%张%'
likeLeft / likeRight 左/右模糊 name LIKE '%张'
in / notIn 包含 id IN (1,2,3)
isNull / isNotNull 空/非空 email IS NULL
orderByAsc / orderByDesc 排序 ORDER BY age ASC
UpdateWrapper
// UPDATE user SET age = 26, name = '王五' WHERE id = 1
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
    .eq(User::getId, 1L)
    .set(User::getAge, 26)
    .set(User::getName, "王五");
userMapper.update(null, wrapper);
动态条件
// condition 为 false 时该条件不会拼入 SQL
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
    .eq(StringUtils.isNotBlank(name), User::getName, name)
    .ge(age != null, User::getAge, age);
嵌套条件
// WHERE name = '张三' AND (age = 20 OR email IS NOT NULL)
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
    .eq(User::getName, "张三")
    .and(w -> w.eq(User::getAge, 20).or().isNotNull(User::getEmail));

3. 分页查询

配置插件
@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);  // 第1页,每页10条

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
    .like(StringUtils.isNotBlank(keyword), User::getName, keyword)
    .orderByDesc(User::getCreateTime);

Page<User> result = userMapper.selectPage(page, wrapper);

result.getRecords();  // 当前页数据
result.getTotal();    // 总记录数
result.getPages();    // 总页数
联表分页
// Mapper 接口
Page<UserVO> selectUserWithDept(Page<UserVO> page,
                                 @Param("ew") LambdaQueryWrapper<User> wrapper);

// XML
// SELECT u.*, d.name AS dept_name
// FROM user u LEFT JOIN department d ON u.dept_id = d.id
// ${ew.customSqlSegment}

4. IService

IService 对 BaseMapper 的进一步封装,提供批量操作和链式调用。

public interface IUserService extends IService<User> {}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements IUserService {}
常用方法
// 增
userService.save(user);
userService.saveBatch(userList);              // 批量(默认每批1000条)

// 删
userService.removeById(1L);
userService.removeByIds(ids);

// 改
userService.updateById(user);
userService.updateBatchById(userList);        // 批量更新

// 查
userService.getById(1L);
userService.list(queryWrapper);
userService.count(queryWrapper);
链式调用
// 链式查询
userService.lambdaQuery()
    .eq(User::getAge, 25)
    .like(User::getName, "张")
    .list();

// 链式更新
userService.lambdaUpdate()
    .set(User::getAge, 30)
    .eq(User::getId, 1L)
    .update();

// 链式删除
userService.lambdaUpdate()
    .eq(User::getAge, 0)
    .remove();

5. 自动填充

实体标注
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
实现 Handler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
    }

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

四、常用注解速查

注解 位置 说明
@TableName 实体类 指定表名
@TableId 主键字段 主键策略
@TableField 普通字段 映射、填充、非数据库字段
@TableLogic 逻辑删除字段 逻辑删除标识
@Version 乐观锁字段 配合乐观锁插件
@EnumValue 枚举字段 枚举值映射
@OrderBy 字段 默认排序

IdType 主键策略

策略 说明
AUTO 数据库自增
INPUT 手动设置
ASSIGN_ID 雪花算法(默认,Long)
ASSIGN_UUID UUID(String)

@TableField 属性

@TableField(value = "email_addr")    // 列名映射
@TableField(exist = false)           // 非数据库字段
@TableField(fill = FieldFill.INSERT) // 自动填充
@TableField(select = false)          // 查询不返回

五、实用技巧

1. 逻辑删除

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0

配置后所有 CRUD 自动适配:deleteById → UPDATE SET deleted=1selectList → 自动追加 WHERE deleted=0

2. 乐观锁

// 配置插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

// 实体
@Version
private Integer version;

// 使用:先查后改,version 自动 +1
User user = userMapper.selectById(1L);  // version = 1
user.setName("新名字");
userMapper.updateById(user);             // WHERE id=1 AND version=1 → version=2

3. 防全表更新/删除

interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// 阻止无 WHERE 条件的 update/delete

4. AR 模式(ActiveRecord)

@Data
@TableName("user")
public class User extends Model<User> { ... }

// 无需注入 Mapper,直接用实体操作
User user = new User();
user.setName("张三");
user.insert();

User found = new User();
found.setId(1L);
found = found.selectById();

速记:继承 BaseMapper 得单表 CRUD,Wrapper 构造条件,IService 加批量和链式调用,分页插件配一行,注解搞定映射和填充。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐