Mybatis-Plus 快速入门

一、why

不做重复的 CRUD 操作

问题1:EmployeeMapper 没有写 crud 方法,为什么在测试类中可以使用?

因为 EmployMapper 接口继承 BaseMapper 接口 ,该接口定义了一系列 crud 方法

问题2:代码不需要写 crud sql 语句,那为什么可以进行 crud 数据操作?

因为 Mybatis-Plus 在项目启动的时候执行 sql 解析

  1. 获取 BaseMapper 接口中指定的 Employee 泛型

  2. 解析泛型数据,得到 employee 的字节码对象

  3. 使用内省方法解析 employee 字节码对象,得到类和属性名

  4. Mybatis-Plus 以类名作为表名,属性名作为列名,进行 sql 拼接,最终得到对应 sql

二、what

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

框架结构

三、how

添加依赖

 
        org.springframework.boot
        spring-boot-starter-parent
        2.4.3
    

    

        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.0
        

        
            com.alibaba
            druid-spring-boot-starter
            1.1.17
        

        
            mysql
            mysql-connector-java
            8.0.22
        

        
            org.springframework.boot
            spring-boot-starter-test
        

        
            org.projectlombok
            lombok
            1.18.16
            provided
        
    

Mysql 8 注意时区问题,配置文件的 url 加上 serverTimezone=UTC

application.properties

#mysql
spring.datasource.url=jdbc:mysql:///mybatis-plus_demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
spring.datasource.username=admin
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

日志

application.properties 中有两种配置 sql 打印日志方式

第一种:

logging.level.cn.jere.plus.mapper=debug

第二种:

# 推荐使用,会自动换行,看 sql 语句比较舒服
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

1、常用注解

@TableName

作用:指定当前实体类映射哪张数据库表, 默认是跟实体类名一致

@TableName("t_employee")
public class Employee {
  //.....
}

@TableField

作用:指定当前属性映射数据库表哪一列, 默认是跟属性名一致

@TableName("employee")
public class Employee {
    
    @TableField(value="eName",exist = false)
    private String name;
}

exist 属性表示当前属性是否映射数据库列。实体类中若该属性在数据库没有的对应的列,要加exist=false

@TableId

作用:标记当前属性映射表主键。

@TableName("employee")
public class Employee {
    @TableId(type = IdType.AUTO) // IdType.AUTO 数据库ID自增
    private Long id;

IdType.ASSIGN_UUID 默认的 id 策略,使用雪花算法生成 long 类型的唯一 id(雪花算法用于分布式微服务)

@Version

作用:用于标记乐观锁操作字段

2、通用 Mapper 接口

insert

/**
 * 插入一条记录
 *
 * @param entity 实体对象
 */
int insert(T entity);

update

  1. updateById (要注意有没有基本数据类型字段)

    使用场景:1. 条件是 id 是更新操作;2. 全量更新

// 需求: 将id=1用户名字修改为jere
   @Test
   public void updateById() {
       Employee employee = new Employee();
       employee.setId(1L);
       employee.setName("jere");
       employeeMapper.updateById(employee);
   }

sql : UPDATE employee SET name=?, age=?, admin=? WHERE id=?

tips : updateById 在拼接 sql 时,把所有非 null 字段都进行 set 拼接

  1. update

    使用场景:1. 条件不仅仅是 id 更新场景(多条件);2. 部分字段更新

   @Test
   public void update() {
       UpdateWrapper wrapper = new UpdateWrapper<>();
       wrapper.eq("id",1L);
       wrapper.set("name","jere24");
       employeeMapper.update(null,wrapper); // 
}

sql : UPDATE employee SET name=? WHERE (id = ?)

wrapper.条件 .set更新字段

delete

  1. deleteById(id)

    // 需求:删除id=20的员工信息
    @Test
    public void deleteById() {
        employeeMapper.deleteById(20L); // DELETE FROM employee WHERE id=?
    }
    
  2. deleteBatchIds(idList)

    // 需求:删除 id=20,id=21 的员工信息
    @Test
    public void deleteBatchIds() {
        employeeMapper.deleteBatchIds(Arrays.asList("20L","21L")); 
        // DELETE FROM employee WHERE id IN ( ? , ? )
    }
    
  3. deleteByMap(map)

    // 需求:删除name=jere并且age=18的员工信息
    @Test
    public void testDeleteByMap() {
        HashMap map = new HashMap();
        map.put("name","jere");
        map.put("age",18);
        employeeMapper.deleteByMap(map); // DELETE FROM employee WHERE name = ? AND age = ?
    }
    
  4. delete(wrapper)

    //需求:删除name=dafei并且age=18的员工信息
    @Test
    public void testDeleteWrapper() {
        UpdateWrapper wrapper = new UpdateWrapper<>();
        wrapper.eq("name","dafei").eq("age",18);
        employeeMapper.delete(wrapper); // DELETE FROM employee WHERE (name = ? AND age = ?)
    }
    

select

  1. selectById(id)

  2. selectBatchIds(idList)

    // 需求:查询id=1,id=2的员工信息
    @Test
    public void testSelectBatchIds(){
        employeeMapper.selectBatchIds(Arrays.asList(1L,2L)); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id IN ( ? , ? )
    }
    
  3. selectByMap(map)

    // 需求: 查询name=dafei, age=18的员工信息
    @Test
    public void testSelectByMap(){
        HashMap map = new HashMap<>();
        map.put("name","dafei");
        map.put("age",18);
        employeeMapper.selectByMap(map); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
    }
    
  4. selectCount(wrapper)

    // 需求: 查询满足条件的所有的员工个数
    @Test
    public void testSelectCount(){
        QueryWrapper wrapper = new QueryWrapper();
        employeeMapper.selectCount(wrapper); // SELECT COUNT( 1 ) FROM employee
        employeeMapper.selectCount(null); // 查询全部 SELECT COUNT( 1 ) FROM employee 
    }
    
  1. selectList(wrapper)

    //需求: 查询满足条件的所有的员工信息, 返回List
    @Test
    public void testSelectList(){
        QueryWrapper wrapper = new QueryWrapper();
        employeeMapper.selectList(wrapper).forEach(System.err::println); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee
    }
    

问题:什么时候使用 selectList ? 什么时候使用 selectMaps ?

如果sql执行完之后的列能封装成实体对象,选用 selectList,如果不能则使用 selectMaps
  1. selectMaps(wrapper)

    用了 group by 返回的列没办法封装到实体对象中,不能用selectList(它的返回值是泛型为实体类的List集合),所以只能用selectMaps

    可以看成:对象即 Map , Map 即对象

    //需求: 查询满足条件的所有的员工信息, 返回List>  底层将每条数据封装成HashMap
    @Test
    public void testSelectMap(){
        QueryWrapper wrapper = new QueryWrapper();
        employeeMapper.selectMaps(wrapper);
    }
    
  1. selectPage(page, wrapper)

    // 需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是实体对象)
    @Test
    public void testSelectPage(){
        QueryWrapper wrapper = new QueryWrapper<>();
        //参数1:当前页, 参数2:每页显示条数
        Page page = new Page<>(2, 3);
        employeeMapper.selectPage(page, wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee LIMIT ?,?
        System.out.println("当前页:" + page.getCurrent());
        System.out.println("每页显示条数:" + page.getSize());
        System.out.println("总页数:" + page.getPages());
        System.out.println("总数:" + page.getTotal());
        System.out.println("当前页数据:" + page.getRecords());
    }
    
  1. selectOne(wrapper)【拓展】

    //需求: 查询满足条件的所有的员工, 取第一条
    @Test
    public void testSelectOne(){
        QueryWrapper wrapper = new QueryWrapper<>();
        Employee employee = employeeMapper.selectOne(wrapper); 
        // 查出结果条数大于1,则抛出异常 Expected one result (or null) to be returned by selectOne(), but found: 19
        System.out.println(employee);
    }
    
  1. selectObjs(wrapper)【拓展】

    //需求: 查询满足条件的所有的员工, 返回排在第一的列所有数据, 没特别指定, 一般返回时id
    @Test
    public void testSelectObjs(){
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.select("name");  //挑选返回的列   SELECT name FROM employee
        List list = employeeMapper.selectObjs(wrapper);
        list.forEach(System.out::println);
    }
      
      
     
    1. selectMapsPage(page, wrapper)【拓展】

       @Test
      public void testSelectMapsPage(){
          QueryWrapper wrapper = new QueryWrapper<>();
          //参数1:当前页, 参数2:每页显示条数
          IPage> page = new Page<>(2, 3);
          employeeMapper.selectMapsPage(page, wrapper);
          System.out.println("当前页:" + page.getCurrent());
          System.out.println("每页显示条数:" + page.getSize());
          System.out.println("总页数:" + page.getPages());
          System.out.println("总数:" + page.getTotal());
          System.out.println("当前页数据:" + page.getRecords());
      }
      

    3、条件构造器

    继承体系

    更新操作

    UpdateWrapper 更新

     @Test
    public void testUpdate2() {
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.eq("id", 1).set("name", "jere");
        employeeMapper.update(null, wrapper); // UPDATE employee SET name=? WHERE (id = ?)
    }
    
     @Test
    public void testUpdate2() {
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.eq("id", 1);
        wrapper.setSql("name='jere'");// sql 片段方式, 上面用 set 是占位符形式
        employeeMapper.update(null, wrapper); // UPDATE employee SET name='jere' WHERE (id = ?)
    }
    

    LambdaUpdateWrapper 更新

    @Test
    public void testUpdate3() {
        LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper();
        wrapper.eq(Employee::getId, 1L).set(Employee::getName,"Jere");
        employeeMapper.update(null, wrapper); //  UPDATE employee SET name=? WHERE (id = ?)
    }
    

    查询操作

    QueryWrapper 查询

    // 需求:查询name=jere, age=18的用户
    @Test
    public void testQuery1(){
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("name", "jere").eq("age", 18);
        System.out.println(employeeMapper.selectList(wrapper));
    }
    

    LambdaQueryWrapper 查询

    // 需求:查询name=dafei, age=18的用户
    @Test
    public void testQuery3(){
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getName, "dafei").eq(Employee::getAge, 18);
        System.out.println(employeeMapper.selectList(wrapper));
    }
    

    工具类 Wrappers

    作用:用于创建各种类型的wrapper

    @Test
    public void testWrappers(){
        //update
        UpdateWrapper updateWrapper1 = new UpdateWrapper<>();
        UpdateWrapper updateWrapper2 = Wrappers.update();
    
        LambdaUpdateWrapper lambdaUpdateWrapper1 = new LambdaUpdateWrapper<>();
        LambdaUpdateWrapper lambdaUpdateWrapper2 = Wrappers.lambdaUpdate();
        //UpdateWrapper -->LambdaUpdateWrapper
        LambdaUpdateWrapper lambdaUpdateWrapper3 = updateWrapper1.lambda();
    
        //select
        QueryWrapper QueryWrapper1 = new QueryWrapper<>();
        QueryWrapper QueryWrapper2 = Wrappers.query();
    
        LambdaQueryWrapper lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        LambdaQueryWrapper lambdaQueryWrapper2 = Wrappers.lambdaQuery();
        //QueryWrapper -->LambdaQueryWrapper
        LambdaQueryWrapper lambdaQueryWrapper3 = QueryWrapper1.lambda();
    }
    

    4、高级查询

    列投影

    select

    // 需求:查询所有员工, 返回员工name, age列
        @Test
        public void testQuery1() {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.select("name,age"); // 用别名就封装不到 employee 对象了
            List employees = employeeMapper.selectList(wrapper);
            employees.forEach(System.err::println);
        }
    

    排序

    orderByAsc / orderByDesc

    orderBy

    // 需求:查询所有员工信息按age正序排, 如果age一样,按id正序排
        @Test
        public void testQuery2() {
            QueryWrapper wrapper = new QueryWrapper();
            boolean flag = true;
            // 参数1:当前参数为 true 时,才执行排序逻辑
    //        wrapper.orderByDesc(flag,"age");
            // 参数1:是否排序开关,true表示排序,false表示不排序
            // 参数2:是否正序排,true表示正序排,false表示倒序排
            // 参数3:排序的列
            wrapper.orderBy(flag, true, "age", "id"); 
            // SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
            List employees = employeeMapper.selectList(wrapper);
        }
    
    // 需求:查询所有员工信息按age正序排, 如果age一样, 按id倒序排
        @Test
        public void testQuery3() {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.orderByAsc("age").orderByDesc("id"); 
            // SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
            employeeMapper.selectList(wrapper);
        }
    

    分组查询

    groupBy

    having

    // 需求: 以部门id进行分组查询,查每个部门员工个数
    @Test
    public void testQuery4() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.select("dept_id,count(1)");
        wrapper.groupBy("dept_id");
        List> maps = employeeMapper.selectMaps(wrapper); 
        // SELECT dept_id,count(1) FROM employee GROUP BY dept_id
    }
    

    group by 什么,则只能 select 什么,统计函数除外

    // 需求: 以部门id进行分组查询,查每个部门员工个数,将大于3人的部门过滤出来
    @Test
    public void testQuery5() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.select("dept_id,count(1) count");
        wrapper.groupBy("dept_id").having("count(1)>3");
        List> maps = employeeMapper.selectMaps(wrapper); 
        // SELECT dept_id,count(1) count FROM employee GROUP BY dept_id HAVING count(1)>3
    }
    

    条件查询

    1. 比较运算符

    allEq / eq / ne

    //需求:查询name=dafei,age=18的员工信息
    @Test
    public void testQuery6() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("name", "Jere").eq("age", 18);
        List employeeList = employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
    }
    

    链式编程返回的是自己,然后继续执行后面的

    // 需求:查询满足条件员工信息,注意传入的map条件中,包含a的列才参与条件查询
    @Test
    public void testQuery7() {
        QueryWrapper wrapper = new QueryWrapper<>();
        Map map = new HashMap<>();
        map.put("name", "dafei");
        map.put("age", 18);
        wrapper.allEq((k, v) -> k.contains("a"), map);
        employeeMapper.selectList(wrapper); 
        //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
    }
    
    //需求:查询name !=dafei员工信息
    @Test
    public void testQuery8() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.ne("name", "Jere");
        List employees = employeeMapper.selectList(wrapper);
    }
    

    gt / ge / lt / le

     // 需求:查询 age 大于18岁员工信息
    @Test
    public void testQuery9() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.gt("age", 18);
        employeeMapper.selectList(wrapper);
    }
    

    between / notBetween

    //需求:查询年龄介于18~30岁的员工信息
    @Test
    public void testQuery10() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.between("age", 18, 30);
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age BETWEEN ? AND ?)
    }
    
    //需求:查询年龄小于18或者大于30岁的员工信息【用between实现】
    @Test
    public void testQuery11() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.notBetween("age", 18, 30);
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age NOT BETWEEN ? AND ?)
    }
    

    isNull / isNotNull

     // 需求: 查询dept_id 为null 员工信息
    @Test
    public void testQuery12() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.isNull("dept_id");
        employeeMapper.selectList(wrapper); 
        //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NULL)
    }
    
    // 需求: 查询dept_id 为不为null 员工信息
    @Test
    public void testQuery13() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.isNotNull("dept_id");
        employeeMapper.selectList(wrapper); 
        //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NOT NULL)
    }
    

    in/notIn / inSql / notInSql

    // 需求: 查询id为1, 2 的员工信息
    @Test
    public void testQuery14() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.in("id", 1, 2);
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (?,?))
    }
    
    // 需求: 查询id不为1, 2 的员工信息
    @Test
    public void testQuery15() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.notIn("id", 1, 2);
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (?,?))
    }
    
    //需求: 查询id为1, 2 的员工信息
    @Test
    public void testQuery16() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.inSql("id", "1,2");
        employeeMapper.selectList(wrapper);
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (1,2))
    }
    
    //需求: 查询id不为1, 2 的员工信息
    @Test
    public void testQuery17() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.notInSql("id", "1,2");
        employeeMapper.selectList(wrapper); // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (1,2))
    }
    

    exists / notExists【拓展】

     @Test
    public void testQuery18() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.exists("select id from department where sn='cwb'");
        employeeMapper.selectList(wrapper);
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (EXISTS (select id from department where sn='cwb'))
    }
    
    2. 模糊查询

    like / notLike

    //需求: 查询name中含有fei字样的员工
    @Test
    public void testQuery19() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.like("name", "fei");
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee where (name LIKE '%fei%');
    }
    
    // 需求: 查询name中不含有fei字样的员工
    @Test
    public void testQuery20() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.notLike("name", "fei");
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id  FROM employee  WHERE (name NOT LIKE '%fei%');
    }
    

    likeLeft / likeRight

    // 需求: 查询name以fei结尾的员工信息
    @Test
    public void testQuery21() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.likeLeft("name", "fei");
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE '%fei');
    }
    
    // 需求: 查询姓王的员工信息
    @Test
    public void testQuery22() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.likeRight("name", "王");
        employeeMapper.selectList(wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE '王%')
    }
    
    3. 逻辑运算符

    or / and

    注意:需要加括号的话在or / and(里面使用 lambda 表达式)

    // 需求: 查询age = 18 或者 name=Jere 或者 id =1 的用户
    @Test
    public void testQuery24() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("age",18);
        wrapper.or();
        wrapper.eq("name","Jere");
        wrapper.or();
        wrapper.eq("id",1);
        employeeMapper.selectList(wrapper); 
    //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ? OR name = ? OR id = ?)
    }
    
    // 需求:查询name含有re字样的,或者 年龄在18到30之间的用户
    @Test
    public void testQuery25() {
        /* QueryWrapper wrapper = new QueryWrapper();
            wrapper.like("name","re");
            wrapper.or();
            wrapper.between("age",18,30);
            employeeMapper.selectList(wrapper);*/
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.like("name","re");
        wrapper.or(wp->wp.ge("age",18).le("age",30));
        employeeMapper.selectList(wrapper);
        //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age >= ? AND age <= ?))
    }
    

    自定义SQL

    1. mapper.xml方式

      
      
      
      
      
      
    1. 注解方式【拓展】

      @Select("select e.* from employee e")
      List listByAnnoSingle();
      
      @Select("select e.*, d.id d_id, d.name d_name, d.sn d_sn from employee e left join department d on e.dept_id = d.id")
      @Results({
          @Result(column="d_id", property = "dept.id"),
          @Result(column="d_name", property = "dept.name"),
          @Result(column="d_sn", property = "dept.sn")
      })
      List listByAnnoJoin();
      

    5、通用 Service 接口

    1. 定义

    Mybatis-Plus 服务层接口定义

    1. 自定义一个接口继承 IService 接口
    2. 明确指定操作实体对象的泛型
    public interface IEmployeeService extends IService {
        //....
    }
    

    Mybatis-Plus 服务层实现类定义

    1. 自定义一个类,继承 ServiceImpl 类,同时实现自定义服务成接口
    2. 明确指定两个泛型:第一个是操作实体类的 mapper 接口,第二个是操作的实体类
    @Service
    @Transactional
    public class EmployeeServiceImpl extends ServiceImpl implements IEmployeeService {
        //....
    }
    

    2. 分页

    步骤1:在启动类配置分页插件

    //分页
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new      PaginationInnerInterceptor(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true); //合理化
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }
    

    步骤2:编写分页代码

    @Getter
    @Setter
    public class QueryObject {
        private int currentPage = 2;// 当前页
        private int pageSize = 3;// 每页显示条数
        private String keyword;// 关键字
    }
    
    //2>query(EmployeeQuery)方法定义
    //3>query(EmployeeQuery)方法实现
    @Override
    public IPage query(QueryObject qo) {
       IPage page = new Page<>(qo.getCurrentPage(), qo.getPageSize()); //设置分页信息
       QueryWrapper wrapper = Wrappers.query(); //拼接条件
       return super.page(page, wrapper);
    }
    
    //需求:查询第2页员工信息, 每页显示3条, 按id排序
    @Test
    public void testPage(){
        QueryObject qo = new QueryObject();
        qo.setPageSize(3);
        qo.setCurrentPage(2);
        IPage page = employeeService.query(qo);
        System.out.println("当前页:" + page.getCurrent());
        System.out.println("总页数:" + page.getPages());
        System.out.println("每页显示条数:" + page.getSize());
        System.out.println("总记录数:" + page.getTotal());
        System.out.println("当前页显示记录:" + page.getRecords());
    }
    

    3. 事务

    贴 @Transactional 注解

    你可能感兴趣的:(Mybatis-Plus 快速入门)