章节索引 :

使用 MyBatis-plus

1. 前言

spring-boot 集成 MyBatis小节中,我们介绍了如何在 spring-boot 中集成 MyBatis,MyBatis 虽然灵活,但是对于业务开发还略显不够。MyBatis-Plus 是国内开发者为 MyBatis 定制的一款增强工具,在不侵入 MyBatis 的基础上能够快速地提升 MyBatis 的开发能力,为开发者节省大量的时间。

提示: 本小节建立在spring-boot 集成 MyBatis小节基础之上,如果你还没有阅读该小节,请务必阅读了解。

2. 简介

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

MyBatis-Plus 内置丰富的基础 mapper 和插件,是目前国内使用最为广泛的开源项目之一。

3. 依赖

在 spring-boot 的基础上,使用 MyBatis-Plus 也十分简单,只需在 pom 文件中添加上对应的 starter 即可。

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.3.1.tmp</version>
</dependency>

4. 准备

MP 提供了十分方便的 BaseMapper 供项目 mapper 继承,如下:

package com.imooc.mybatis.springbootmybatisexample.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.imooc.mybatis.springbootmybatisexample.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;

@Mapper
@Repository
public interface UserMapper extends BaseMapper<User> {

  @Select("SELECT * FROM imooc_user")
  List<User> getUsers();
}

UserMapper 继承 BaseMapper 后就拥有了基础的增删查改功能,而无需写 SQL。BaseMapper 必须指定一个与 UserMapper 对应的模型类,即 User 类。

package com.imooc.mybatis.springbootmybatisexample.model;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;

@TableName("imooc_user")
public class User implements Serializable {
  @TableId("id")
  private Long id;
  private String username;
  private Integer age;
  private Integer score;
  // 省略诸多 getter 和 setter 方法
}

在模型类中,我们需要通过 TableName 注解指定模型对于的数据表名称,并通过 TableId 注解指定数据表字段。

并在 SpringbootMybatisExampleApplication 启动类上添加 MapperScan 注解来扫描 mapper,如下:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.imooc.mybatis.springbootmybatisexample.mapper")
public class SpringbootMybatisExampleApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringbootMybatisExampleApplication.class, args);
  }
}

MapperScan 中需填入 mapper 所在的包路径,即 com.imooc.mybatis.springbootmybatisexample.mapper。

5. 使用

5.1 基础使用

接下来,我们在 UserController 中来使用增强后的 UserMapper。

package com.imooc.mybatis.springbootmybatisexample.controller;

import com.imooc.mybatis.springbootmybatisexample.mapper.UserMapper;
import com.imooc.mybatis.springbootmybatisexample.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
  @Autowired
  private UserMapper userMapper;

  @GetMapping
  public List<User> getUsers() {
    // return userMapper.getUsers();
    return userMapper.selectList(null);
  }
}

这里,我们替换了之前使用的 getUsers 方法,而是使用了 BaseMapper 提供的 selectList 方法,该方法接收一个参数,这里我们暂时定为 null。

运行程序,并通过 curl 测试接口:

# curl 127.0.0.1:8080/user/
[{"id":1,"username":"peter","age":18,"score":100},{"id":2,"username":"pedro","age":24,"score":200},{"id":3,"username":"jerry","age":28,"score":500},{"id":4,"username":"mike","age":12,"score":300}]

我们仍然取得了与之前一样的结果。可以看到,MP 在增强 UserMapper 后,我们无需再写多余的 SQL,MP 自动的为我们生成了对应的 SQL 语句。

5.2 进阶使用

MP 的功能远不止如此简单,我们还可以通过 Java API 给 selectList 函数传入 SQL 筛选条件。如,我们只想获取分数大于 200 分的用户。

@RestController
@RequestMapping("/user")
public class UserController {
  @Autowired
  private UserMapper userMapper;

  @GetMapping
  public List<User> getUsers() {
    QueryWrapper<User> condition = new QueryWrapper<>();
    condition.lambda().gt(User::getScore, 200);
    return userMapper.selectList(condition);
  }
}

QueryWrapper 是 MP 提供的查询条件包装器,通过 Java API 的方式我们就可以构造 SQL 过滤条件。如这里我们通过 lamdba 表示式构造了用户积分需大于200的过滤条件,然后将包装器以参数的形式传递给 selectList 函数。

再次运行程序,并通过 curl 测试接口:

# curl 127.0.0.1:8080/user/
[{"id":3,"username":"jerry","age":28,"score":500},{"id":4,"username":"mike","age":12,"score":300},{"id":5,"username":"tom","age":27,"score":1000}]

从结果中,可以看出积分小于200的用户都已经被过滤掉了。

5.3 分页插件

MP 内置提供了分页插件,只需几行代码我们就可直接引入。

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;

@SpringBootApplication
@MapperScan("com.imooc.mybatis.springbootmybatisexample.mapper")
public class SpringbootMybatisExampleApplication {
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
  }
  public static void main(String[] args) {
    SpringApplication.run(SpringbootMybatisExampleApplication.class, args);
  }
}

在 SpringbootMybatisExampleApplication 启动类中,我们添加了一个带有 Bean 注解的 paginationInterceptor 方法,该方法返回一个 PaginationInterceptor 对象,这样插件就配置完成了。

接下来,我们来使用它。

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@RestController
@RequestMapping("/user")
public class UserController {
  @Autowired
  private UserMapper userMapper;

  @GetMapping
  public List<User> getUsers() {
    Page page = userMapper.selectPage(new Page<>(1, 3), null);
    return page.getRecords();
  }
}

UserMapper 的 selectPage 方法接受两个参数,第一个参数是分页配置,第二个参数是查询条件包装器。这里第一个参数,我们直接通过 Page 构造函数来构造,1 表示当前页,3 表示分页最大的记录数,即第一页且最多返回三条记录;第二个参数我们直接设置为 null。

运行程序,并通过 curl 测试接口:

# curl 127.0.0.1:8080/user/
[{"id":1,"username":"peter","age":18,"score":100},{"id":2,"username":"pedro","age":24,"score":200},{"id":3,"username":"jerry","age":28,"score":500}]

从结果可以看出,分页生效了,记录总数却是为 3 条。

6. 小结

  • MyBatis-Plus 是国内使用十分广泛的一款 ORM 库,极大的节省了开发者的开发时间,功能强大且使用简单。
  • MyBatis-Plus 的内容还是较多的,如果你感兴趣,不妨访问它的官网看一看。