Loading

Mybatis-Plus

Mybatis-Plus 总结

一、why

不做重复的 CRUD 操作

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

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

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

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

1. 获取 BaseMapper 接口中指定的 Employee 泛型
2. 解析泛型数据,得到 employee 的字节码对象
  1. 使用内省方法解析 employee 字节码对象,得到类和属性名

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

框架结构

二、what

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

三、how

添加依赖

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
    </parent>

    <dependencies>

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

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

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

application.properties

#mysql
spring.datasource.url=jdbc:mysql://localhost:3306/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 拼接

  2. update

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

    @Test
    public void update() {
        UpdateWrapper<Employee> 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<String,Object> 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<Employee> 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<String, Object> 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<Employee> wrapper = new QueryWrapper();
        employeeMapper.selectCount(wrapper); // SELECT COUNT( 1 ) FROM employee
        employeeMapper.selectCount(null); // 查询全部 SELECT COUNT( 1 ) FROM employee 
    }
    
  5. selectList(wrapper)

    //需求: 查询满足条件的所有的员工信息, 返回List<Employee>
    @Test
    public void testSelectList(){
        QueryWrapper<Employee> 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

  6. selectMaps(wrapper)

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

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

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

    // 需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是实体对象)
    @Test
    public void testSelectPage(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        //参数1:当前页, 参数2:每页显示条数
        Page<Employee> 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());
    }
    
  8. selectOne(wrapper)【拓展】

    //需求: 查询满足条件的所有的员工, 取第一条
    @Test
    public void testSelectOne(){
        QueryWrapper<Employee> 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);
    }
    
  9. selectObjs(wrapper)【拓展】

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

     @Test
    public void testSelectMapsPage(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        //参数1:当前页, 参数2:每页显示条数
        IPage<Map<String, Object>> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> updateWrapper1 = new UpdateWrapper<>();
    UpdateWrapper<Employee> updateWrapper2 = Wrappers.<Employee>update();

    LambdaUpdateWrapper<Employee> lambdaUpdateWrapper1 = new LambdaUpdateWrapper<>();
    LambdaUpdateWrapper<Employee> lambdaUpdateWrapper2 = Wrappers.<Employee>lambdaUpdate();
    //UpdateWrapper -->LambdaUpdateWrapper
    LambdaUpdateWrapper<Employee> lambdaUpdateWrapper3 = updateWrapper1.lambda();

    //select
    QueryWrapper<Employee> QueryWrapper1 = new QueryWrapper<>();
    QueryWrapper<Employee> QueryWrapper2 = Wrappers.<Employee>query();

    LambdaQueryWrapper<Employee> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
    LambdaQueryWrapper<Employee> lambdaQueryWrapper2 = Wrappers.<Employee>lambdaQuery();
    //QueryWrapper -->LambdaQueryWrapper
    LambdaQueryWrapper<Employee> lambdaQueryWrapper3 = QueryWrapper1.lambda();
}

4、高级查询

列投影

select

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

排序

orderByAsc / orderByDesc

orderBy

// 需求:查询所有员工信息按age正序排, 如果age一样,按id正序排
    @Test
    public void testQuery2() {
        QueryWrapper<Employee> 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<Employee> employees = employeeMapper.selectList(wrapper);
    }
// 需求:查询所有员工信息按age正序排, 如果age一样, 按id倒序排
    @Test
    public void testQuery3() {
        QueryWrapper<Employee> 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<Employee> wrapper = new QueryWrapper();
    wrapper.select("dept_id,count(1)");
    wrapper.groupBy("dept_id");
    List<Map<String, Object>> 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<Employee> wrapper = new QueryWrapper();
    wrapper.select("dept_id,count(1) count");
    wrapper.groupBy("dept_id").having("count(1)>3");
    List<Map<String, Object>> 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<Employee> wrapper = new QueryWrapper();
    wrapper.eq("name", "Jere").eq("age", 18);
    List<Employee> 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<Employee> wrapper = new QueryWrapper<>();
    Map<String, Object> 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<Employee> wrapper = new QueryWrapper();
    wrapper.ne("name", "Jere");
    List<Employee> employees = employeeMapper.selectList(wrapper);
}

gt / ge / lt / le

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

between / notBetween

//需求:查询年龄介于18~30岁的员工信息
@Test
public void testQuery10() {
    QueryWrapper<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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方式

    <!--单表-->
    <select id="listByXmlSingle" resultMap="BaseResultMap">
        select id, name, password, email, age, admin, dept_id
        from employee
    </select>
    
    <!--多表-->
    <select id="listByXmlJoin" resultMap="BaseResultMap">
        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
    </select>
    
  2. 注解方式【拓展】

    @Select("select e.* from employee e")
    List<Employee> 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<Employee> listByAnnoJoin();
    

5、通用 Service 接口

1. 定义

Mybatis-Plus 服务层接口定义

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

Mybatis-Plus 服务层实现类定义

  1. 自定义一个类,继承 ServiceImpl 类,同时实现自定义服务成接口
  2. 明确指定两个泛型:第一个是操作实体类的 mapper 接口,第二个是操作的实体类
@Service
@Transactional
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> 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<Employee> query(QueryObject qo) {
   IPage<Employee> page = new Page<>(qo.getCurrentPage(), qo.getPageSize()); //设置分页信息
   QueryWrapper<Employee> wrapper = Wrappers.<Employee>query(); //拼接条件
   return super.page(page, wrapper);
}
//需求:查询第2页员工信息, 每页显示3条, 按id排序
@Test
public void testPage(){
    QueryObject qo = new QueryObject();
    qo.setPageSize(3);
    qo.setCurrentPage(2);
    IPage<Employee> 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 注解

posted @ 2021-08-06 20:36  JereCode  阅读(60)  评论(0编辑  收藏  举报