Skip to content

MyBatis-Plus 简介

什么是MyBatis-Plus?

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

核心特性

1. 无侵入

只做增强不做改变,引入它不会对现有工程产生影响。

2. 损耗小

启动即会自动注入基本CRUD,性能基本无损耗,直接面向对象操作。

3. 强大的CRUD操作

内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作。

4. 支持Lambda形式

通过Lambda表达式,方便的编写各类查询条件,无需担心字段写错。

5. 支持主键自动生成

支持多达4种主键策略,可自由配置,完美解决主键问题。

6. 支持ActiveRecord模式

支持ActiveRecord形式调用,实体类只需继承Model类即可进行强大的CRUD操作。

7. 支持自定义全局通用操作

支持全局通用方法注入。

8. 内置代码生成器

采用代码或Maven插件可快速生成Mapper、Model、Service、Controller层代码。

9. 内置分页插件

基于MyBatis物理分页,开发者无需关心具体操作,配置好插件后,写分页等同于普通List查询。

10. 内置性能分析插件

可输出SQL语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。

11. 内置全局拦截插件

提供全表delete、update操作智能分析阻断,也可自定义拦截规则,预防误操作。

快速开始

1. 添加依赖

Maven:

xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.5</version>
</dependency>

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

2. 配置数据源

application.yml:

yaml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: password

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # SQL日志
    map-underscore-to-camel-case: true # 下划线转驼峰
  global-config:
    db-config:
      id-type: auto # 主键自增
      table-prefix: t_ # 表名前缀
      logic-delete-field: deleted # 逻辑删除字段
      logic-delete-value: 1 # 逻辑删除值
      logic-not-delete-value: 0 # 逻辑未删除值
  mapper-locations: classpath*:/mapper/**/*.xml

3. 创建实体类

java
@Data
@TableName("user") // 指定表名
public class User {
    
    @TableId(type = IdType.AUTO) // 主键自增
    private Long id;
    
    @TableField("user_name") // 指定字段名
    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;
    
    @Version // 乐观锁
    private Integer version;
    
    @TableField(exist = false) // 非数据库字段
    private String extra;
}

4. 创建Mapper接口

java
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 继承BaseMapper后,无需编写任何代码即可使用CRUD方法
}

5. 使用BaseMapper

java
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    // 插入
    public void insert() {
        User user = new User();
        user.setUsername("张三");
        user.setEmail("zhangsan@example.com");
        user.setAge(25);
        userMapper.insert(user);
    }
    
    // 根据ID查询
    public User getById(Long id) {
        return userMapper.selectById(id);
    }
    
    // 查询所有
    public List<User> getAll() {
        return userMapper.selectList(null);
    }
    
    // 更新
    public void update() {
        User user = userMapper.selectById(1L);
        user.setAge(26);
        userMapper.updateById(user);
    }
    
    // 删除
    public void delete(Long id) {
        userMapper.deleteById(id);
    }
}

BaseMapper方法

MyBatis-Plus提供的通用CRUD方法:

Insert

java
// 插入一条记录
int insert(T entity);

Delete

java
// 根据 ID 删除
int deleteById(Serializable id);

// 根据 columnMap 条件删除
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

// 根据 entity 条件删除
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

// 根据 ID 批量删除
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

Update

java
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

// 根据 whereWrapper 条件修改 entity
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

Select

java
// 根据 ID 查询
T selectById(Serializable id);

// 根据 ID 批量查询
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

// 根据 columnMap 条件查询
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

// 根据 wrapper 条件查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 wrapper 条件查询总记录数
Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 wrapper 条件查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 wrapper 条件查询全部记录并分页
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

条件构造器

QueryWrapper

java
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    // 基本条件
    public List<User> queryExample1() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", "张三")  // username = '张三'
               .ne("age", 18)          // AND age != 18
               .gt("age", 20)          // AND age > 20
               .ge("age", 18)          // AND age >= 18
               .lt("age", 30)          // AND age < 30
               .le("age", 25);         // AND age <= 25
        return userMapper.selectList(wrapper);
    }
    
    // 模糊查询
    public List<User> queryExample2() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("username", "张")          // username LIKE '%张%'
               .likeLeft("username", "三")      // username LIKE '%三'
               .likeRight("username", "张");    // username LIKE '张%'
        return userMapper.selectList(wrapper);
    }
    
    // IN查询
    public List<User> queryExample3() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.in("id", 1, 2, 3, 4, 5);        // id IN (1,2,3,4,5)
        return userMapper.selectList(wrapper);
    }
    
    // BETWEEN
    public List<User> queryExample4() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age", 18, 30);         // age BETWEEN 18 AND 30
        return userMapper.selectList(wrapper);
    }
    
    // IS NULL / IS NOT NULL
    public List<User> queryExample5() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.isNull("email")                 // email IS NULL
               .isNotNull("username");          // AND username IS NOT NULL
        return userMapper.selectList(wrapper);
    }
    
    // OR条件
    public List<User> queryExample6() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", "张三")
               .or()
               .eq("username", "李四");          // username = '张三' OR username = '李四'
        return userMapper.selectList(wrapper);
    }
    
    // 嵌套查询
    public List<User> queryExample7() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", "张三")
               .and(w -> w.eq("age", 25).or().eq("age", 30));
        // username = '张三' AND (age = 25 OR age = 30)
        return userMapper.selectList(wrapper);
    }
    
    // 排序
    public List<User> queryExample8() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("age")               // ORDER BY age ASC
               .orderByDesc("create_time");     // , create_time DESC
        return userMapper.selectList(wrapper);
    }
    
    // 选择字段
    public List<User> queryExample9() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.select("id", "username", "email");  // SELECT id, username, email
        return userMapper.selectList(wrapper);
    }
}

LambdaQueryWrapper(推荐)

使用Lambda表达式,避免字段名写错:

java
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    public List<User> queryWithLambda() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, "张三")
               .gt(User::getAge, 18)
               .like(User::getEmail, "@example.com")
               .orderByDesc(User::getCreateTime);
        return userMapper.selectList(wrapper);
    }
    
    // 条件动态拼接
    public List<User> queryDynamic(String username, Integer minAge, Integer maxAge) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(username), User::getUsername, username)
               .ge(minAge != null, User::getAge, minAge)
               .le(maxAge != null, User::getAge, maxAge);
        return userMapper.selectList(wrapper);
    }
}

UpdateWrapper

java
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    public void updateExample1() {
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.eq("username", "张三")
               .set("age", 26)
               .set("email", "new@example.com");
        userMapper.update(null, wrapper);
    }
    
    // Lambda方式
    public void updateExample2() {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getUsername, "张三")
               .set(User::getAge, 26)
               .set(User::getEmail, "new@example.com");
        userMapper.update(null, wrapper);
    }
}

分页查询

1. 配置分页插件

java
@Configuration
public class MybatisPlusConfig {
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        
        // 分页插件
        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
        paginationInterceptor.setDbType(DbType.MYSQL);
        paginationInterceptor.setOverflow(false); // 溢出总页数后是否进行处理
        paginationInterceptor.setMaxLimit(500L); // 单页分页条数限制
        
        interceptor.addInnerInterceptor(paginationInterceptor);
        
        return interceptor;
    }
}

2. 使用分页

java
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    public IPage<User> pageQuery(int current, int size) {
        Page<User> page = new Page<>(current, size);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.gt(User::getAge, 18)
               .orderByDesc(User::getCreateTime);
        return userMapper.selectPage(page, wrapper);
    }
}
java
@RestController
@RequestMapping("/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/page")
    public IPage<User> page(@RequestParam(defaultValue = "1") int current,
                            @RequestParam(defaultValue = "10") int size) {
        return userService.pageQuery(current, size);
    }
}

IService接口

MyBatis-Plus提供了IService接口,包含更多实用方法。

1. 创建Service接口和实现

java
public interface UserService extends IService<User> {
    // 自定义方法
}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 自定义方法实现
}

2. 使用IService方法

java
@RestController
@RequestMapping("/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 保存
    @PostMapping
    public boolean save(@RequestBody User user) {
        return userService.save(user);
    }
    
    // 批量保存
    @PostMapping("/batch")
    public boolean saveBatch(@RequestBody List<User> users) {
        return userService.saveBatch(users);
    }
    
    // 保存或更新
    @PostMapping("/saveOrUpdate")
    public boolean saveOrUpdate(@RequestBody User user) {
        return userService.saveOrUpdate(user);
    }
    
    // 根据ID查询
    @GetMapping("/{id}")
    public User getById(@PathVariable Long id) {
        return userService.getById(id);
    }
    
    // 条件查询一条
    @GetMapping("/one")
    public User getOne(@RequestParam String username) {
        return userService.getOne(
            new LambdaQueryWrapper<User>().eq(User::getUsername, username)
        );
    }
    
    // 查询列表
    @GetMapping("/list")
    public List<User> list() {
        return userService.list();
    }
    
    // 条件查询列表
    @GetMapping("/listByAge")
    public List<User> listByAge(@RequestParam Integer age) {
        return userService.list(
            new LambdaQueryWrapper<User>().gt(User::getAge, age)
        );
    }
    
    // 分页查询
    @GetMapping("/page")
    public IPage<User> page(@RequestParam int current, @RequestParam int size) {
        return userService.page(new Page<>(current, size));
    }
    
    // 更新
    @PutMapping
    public boolean updateById(@RequestBody User user) {
        return userService.updateById(user);
    }
    
    // 根据ID删除
    @DeleteMapping("/{id}")
    public boolean removeById(@PathVariable Long id) {
        return userService.removeById(id);
    }
    
    // 批量删除
    @DeleteMapping("/batch")
    public boolean removeBatchByIds(@RequestBody List<Long> ids) {
        return userService.removeBatchByIds(ids);
    }
    
    // 统计
    @GetMapping("/count")
    public long count() {
        return userService.count();
    }
}

下一步

最后更新于: