大纲 前言 版本说明 本文的教程内容是基于 MyBatis-Plus 3.5.2
版本编写的,若你使用的是 2.x
或其他版本,可能会有部分知识点、案例代码不兼容,一切以 MyBatis-Plus 官方文档为准。
条件构造器 提示
1、MyBatis-Plus 条件构造器的条件参数详细介绍可看 这里 。 2、本文所需的案例代码,可以直接从 GitHub 下载对应章节 mybatis-plus-lesson-05
。
Wrapper 介绍
Wrapper : 条件构造抽象类,最顶端父类 AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件 QueryWrapper : 查询条件封装 UpdateWrapper : Update 条件封装 AbstractLambdaWrapper : 使用 Lambda 语法 LambdaQueryWrapper : 用于 Lambda 语法使用的查询 Wrapper LambdaUpdateWrapper : Lambda 更新封装 Wrapper QueryWrapper 组装查询条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void selectList () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.like("last_name" , 'i' ); wrapper.isNotNull("email" ); wrapper.between("age" , 20 , 25 ); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee WHERE (last_name LIKE ? AND email IS NOT NULL AND age BETWEEN ? AND ?)
组装排序条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void orderBy () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.orderByDesc("age" ); wrapper.orderByAsc("last_name" ); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee ORDER BY age DESC ,last_name ASC
组装删除条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void delete () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.isNull("email" ); Integer deleteResult = empMapper.delete(wrapper); System.out.println("deleteResult: " + deleteResult); } }
1 DELETE FROM t_employee WHERE (email IS NULL )
组装更新条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void update () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.ge("age" , 26 ); Employee employee = new Employee(); employee.setLastName("Jim" ); Integer updateResult = empMapper.update(employee, wrapper); System.out.println("updateResult: " + updateResult); } }
1 UPDATE t_employee SET last_name= ? WHERE (age >= ?)
条件的优先级 提示
当存在多个条件时,Lambda 表达式中的条件优先执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void conditionOrder () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.like("last_name" , "a" ).and(i -> i.gt("age" , 26 ).or().isNull("email" )); Employee employee = new Employee(); employee.setLastName("Albert" ); Integer updateResult = empMapper.update(employee, wrapper); System.out.println("updateResult: " + updateResult); } }
1 UPDATE t_employee SET last_name= ? WHERE (last_name LIKE ? AND (age > ? OR email IS NULL ))
组装 Select 语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void selectColumns () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.select("last_name" , "gender" ); List<Map<String, Object>> list = empMapper.selectMaps(wrapper); list.forEach(System.out::println); } }
1 SELECT last_name,gender FROM t_employee
组装嵌套子查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void nestedSubSelect () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.inSql("id" , "select id from t_employee where age <= 28" ); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee WHERE (id IN (select id from t_employee where age <= 28 ))
Condition 组装条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @SpringBootTest public class QueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void condition () { Integer minAge = 25 ; Integer maxAge = null ; String lastName = "j" ; QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.like(StringUtils.isNotBlank(lastName), "last_name" , lastName); wrapper.ge(minAge != null , "age" , minAge); wrapper.le(maxAge != null , "age" , maxAge); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee WHERE (last_name LIKE ? AND age >= ?)
UpdateWrapper 组装更新条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @SpringBootTest public class UpdateWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void update () { UpdateWrapper<Employee> wrapper = new UpdateWrapper<>(); wrapper.like("last_name" , "a" ); wrapper.gt("age" , 27 ); wrapper.set("gender" , "1" ); wrapper.set("email" , null ); Integer updateResult = empMapper.update(null , wrapper); System.out.println("updateResult: " + updateResult); } }
1 UPDATE t_employee SET gender= ?,email= ? WHERE (last_name LIKE ? AND age > ?)
组装更新 SQL 语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @SpringBootTest public class UpdateWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void updateSql () { UpdateWrapper<Employee> wrapper = new UpdateWrapper<>(); wrapper.like("last_name" , "a" ); wrapper.gt("age" , 27 ); wrapper.setSql("gender = '1' and email = null" ); Integer updateResult = empMapper.update(null , wrapper); System.out.println("updateResult: " + updateResult); } }
1 UPDATE t_employee SET gender = '1' and email = null WHERE (last_name LIKE ? AND age > ?)
LambdaQueryWrapper 值得一提的是,使用 LambdaQueryWrapper
的好处是可以防止表字段的名称被拼接错。
组装查询条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @SpringBootTest public class LambdaQueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void selectList () { LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>(); wrapper.like(Employee::getLastName, 'j' ) .le(Employee::getAge, 28 ) .eq(Employee::getGender, "1" ); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee WHERE (last_name LIKE ? AND age <= ? AND gender = ?)
条件的优先级 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @SpringBootTest public class LambdaQueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void conditionOrder () { LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Employee::getLastName, "jim" ); wrapper.and(i -> i.gt(Employee::getAge, 26 ).or().isNull(Employee::getEmail)); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee WHERE (last_name = ? AND (age > ? OR email IS NULL ))
Condition 组装条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @SpringBootTest public class LambdaQueryWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void condition () { Integer minAge = 25 ; Integer maxAge = null ; String lastName = "j" ; LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>(); wrapper.like(StringUtils.isNotBlank(lastName), Employee::getLastName, lastName) .ge(minAge != null , Employee::getAge, minAge) .le(maxAge != null , Employee::getAge, maxAge); List<Employee> list = empMapper.selectList(wrapper); list.forEach(System.out::println); } }
1 SELECT id,last_name,gender,email,age FROM t_employee WHERE (last_name LIKE ? AND age >= ?)
LambdaUpdateWrapper 值得一提的是,使用 LambdaUpdateWrapper
的好处是可以防止表字段的名称被拼接错。
组装更新条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @SpringBootTest public class LambdaUpdateWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void update () { LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>(); wrapper.like(Employee::getLastName, "a" ) .gt(Employee::getAge, 27 ) .set(Employee::getGender, "1" ) .set(Employee::getEmail, null ); Integer updateResult = empMapper.update(null , wrapper); System.out.println("updateResult: " + updateResult); } }
1 UPDATE t_employee SET gender= ?,email= ? WHERE (last_name LIKE ? AND age > ?)
组装更新 SQL 语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @SpringBootTest public class LambdaUpdateWrapperTest { @Autowired private EmployeeMapper empMapper; @Test public void updateSql () { LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>(); wrapper.like(Employee::getLastName, "a" ) .gt(Employee::getAge, 27 ) .setSql("gender = '1' and email = null" ); Integer updateResult = empMapper.update(null , wrapper); System.out.println("updateResult: " + updateResult); } }
1 UPDATE t_employee SET gender = '1' and email = null WHERE (last_name LIKE ? AND age > ?)
ActiveRecord 模式 Active Record(活动记录)是一种领域模型模式,简称 AR 模式;特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。ActiveRecord 一直广受动态语言(PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MyBatis-Plus 也在 ActiveRecord 道路上进行了一定的探索。
使用 ActiveRecord 模式 使用 ActiveRecord 模式时,仅仅需要让实体类继承 Model
类,并实现指定主键的 pkVal()
方法即可。值得一提的是,如果主键属性的名称本来就是 id
,则可以忽略实现 pkVal()
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Employee extends Model <Employee > { private Long id; private String lastName; private String gender; private String email; private Integer age; ... @Override public Serializable pkVal () { return this .id; } }
特别注意
必须存在对应的原始 Mapper 接口,并继承 BaseMapper
接口(如下所示)的前提下才能使用 ActiveRecord 模式!
1 2 3 public interface EmployeeMapper extends BaseMapper <Employee > {}
ActiveRecord 模式操作 由于 Model
类提供了通用的 CRUD 方法,因此实体类继承 Model
类之后,可以直接执行 CRUD 操作。本节所需的案例代码,可以直接从 GitHub 下载对应章节 mybatis-plus-lesson-06
。
查询数据操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 @SpringBootTest public class ActiveRecordTest { @Test public void selectById () { Employee employee = new Employee(); employee.setId(1L ); Employee result = employee.selectById(); System.out.println(result); } @Test public void selectAll () { Employee employee = new Employee(); List<Employee> list = employee.selectAll(); list.forEach(System.out::println); } @Test public void selectByWrapper () { QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.like("last_name" , "j" ); wrapper.eq("gender" , "1" ); Employee employee = new Employee(); List<Employee> list = employee.selectList(wrapper); list.forEach(System.out::println); } @Test public void selectCount () { Employee employee = new Employee(); Long count = employee.selectCount(null ); System.out.println("count: " + count); } }
插入数据操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @SpringBootTest public class ActiveRecordTest { @Test public void insert () { Employee employee = new Employee(); employee.setAge(24 ); employee.setGender("1" ); employee.setLastName("David" ); employee.setEmail("david@gmail.com" ); boolean insertResult = employee.insert(); System.out.println("insertResult: " + insertResult); } }
更新数据操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @SpringBootTest public class ActiveRecordTest { @Test public void updateById () { Employee employee = new Employee(); employee.setId(1L ); employee.setAge(24 ); employee.setGender("1" ); boolean updateResult = employee.updateById(); System.out.println("updateResult: " + updateResult); } @Test public void updateByWrapper () { QueryWrapper<Employee> wraper = new QueryWrapper<>(); wraper.isNull("email" ); wraper.eq("gender" , "1" ); Employee employee = new Employee(); employee.setAge(24 ); boolean updateResult = employee.update(wraper); System.out.println("updateResult: " + updateResult); } }
删除数据操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @SpringBootTest public class ActiveRecordTest { @Test public void deleteById () { Employee employee = new Employee(); employee.setId(11L ); boolean deleteResult = employee.deleteById(); System.out.println("deleteResult: " + deleteResult); } @Test public void deleteByWrapper () { QueryWrapper<Employee> wraper = new QueryWrapper<>(); wraper.isNull("email" ); wraper.eq("gender" , "1" ); Employee employee = new Employee(); boolean deleteResult = employee.delete(wraper); System.out.println("deleteResult: " + deleteResult); } }