学习要求
良好的java基础, 熟悉SpringBoot框架,熟悉Mybatis框架
教程目标
了解并掌握MyBatis-Plus各种条件查询
视频教程
概要
1> 前一篇重点介绍了mybatis-plus中的wrapper体系与操作方式,本篇重点讲的wrapper中的query操作,以QueryWrapper 实例为切入点,讲解常用的条件查询,UpdateWrapper涉及到的条件同理可得即可。
2>一样沿用前几篇使用的employee 表/实体/mapper等代码
@Setter
@Getter
@ToString
@TableName("employee")
public class Employee {
@TableId(value = "id", type= IdType.AUTO)
private Long id;
@TableField(value = "name", exist = true)
private String name;
private String password;
private String email;
private int age;
private int admin;
private Long deptId;
}
下面就是SQL具体分类操作
列投影(映射)
select
重载的方法有3个,其实就2个,一个功能重复了
用法:从查询结果集中挑选指定列
需求:查询所有员工信息,返回员工的age跟name属性
select(String....)
@Test
public void testQuery1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("name", "age"); //列的投影, 挑选哪一些列, 参数是列名
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
SELECT name,age FROM employee
使用注意,如果列使用别名,那就按照sql编写别名方式写,换句话讲select里面参数其实就是sql中的select语句,语法一样
wrapper.select("name as ename", "age as eage");
SELECT name as ename,age as eage FROM employee
还有简便的写法:sql片段方式
@Test
public void testQuery1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//wrapper.select("name", "age"); //列的投影, 挑选哪一些列, 参数是列名
wrapper.select("name, age"); //参数是sql 片段
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)
这个方法理解起来相对麻烦
enittyClass: 表示指定查询实体对象,比如:当前操作员工表,那么指定Employee.class
predicate:判断型函数接口,接口有个test方法,参数是TableFieldInfo
TableFieldInfo:表字段信息对象,将表的列抽象成java对象
方法意思:指定查询对象,使用predicate定义条件列的规则,满足条件的列,挑选出来。
需求:查询列名以 字母 "e" 结尾的列
@Test
public void testQuery1_1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select(Employee.class, tableFieldInfo -> tableFieldInfo.getColumn().endsWith("e"));
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
SELECT id,name,age FROM employee
查询出来的列有id,name, age。 id是默认查询,name 跟 age 列都有e字母,所以能查询出来
需求2:查询列名长度大于 5的列
@Test
public void testQuery1_1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select(Employee.class, tableFieldInfo -> tableFieldInfo.getColumn().length() > 5);
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
SELECT id,password,dept_id FROM employee
排序
mybatis-plus的排序有8个,具体分为3种:orderByAsc / orderByDesc / orderBy
orderByAsc : 倒序排 3个
orderByDesc : 倒序排 3个
orderBy:1个
用法:对查询结果集排序,可以单列排,可以多列排
orderByAsc(String column)/orderByDesc(String column) : 单列正排序/倒排序
需求:查询所有员工信息,按age正序排/倒序排
@Test
public void testQuery2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age"); //正序
//wrapper.orderByDesc("age"); //倒序
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
-- 正序
SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC
-- 倒序
-- SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age DESC
需求:查询所有员工信息,按age正序排, 如果age 一样,按id正序排
需求:查询所有员工信息,按age正序排, 如果age 一样,按id倒序排
@Test
public void testQuery2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age");
wrapper.orderByAsc("id"); //正序
//wrapper.orderByDesc("id"); //倒序
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
-- 先正序后正序
SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
-- 先正序后倒序
-- SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
这里注意,mybatis-plus列排序谁先谁后是根据orderBy方法调用顺序,操作时务必小心
orderByAsc(String... column)/orderByDesc(String... column) : 多列正排序/倒排序
需求:查询所有员工信息,按age正序排, 如果age 一样,按id正序排
需求:查询所有员工信息,按age倒序排, 如果age 一样,按id倒序排
@Test
public void testQuery2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age", "id"); //都正序
//wrapper.orderByDesc("age", "id"); //都倒序
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
-- 都是正序
SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
-- 都是倒序
-- SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age DESC,id DESC
从上面也可以看出多列排序其实跟单列排序本质一样没啥区别
orderByAsc(boolean condition, String... column)/orderByDesc(boolean condition, String... column) : 带条件判断多列正排序/倒排序
condition:排序控制开关,当condition这个参数为true时,才对sql语句进行排序操作
需求:当orderby变量不为null 时,使用orderby变量进行正序排
@Test
public void testQuery2_1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//String orderBy = "age"; //有值
String orderBy = null; //没值
wrapper.orderByAsc(StringUtils.hasText(orderBy), orderBy);
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行完SQL
-- 有值
-- SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC
-- 没值
SELECT id,name,password,email,age,admin,dept_id FROM employee
orderBy(boolean condition, boolean isAsc,String... columns) : 带条件判断多列排序
condition: 当condition这个参数为true时,才对sql语句进行排序操作
isAsc:是否为正序排, true:表示正序, false:表示倒序
columns:排序的列,可以多列,可单列
需求:当orderby变量不为null 时,使用orderby变量进行正序排
需求:当orderby变量不为null 时,使用orderby变量进行倒序排
@Test
public void testQuery2_2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
String orderBy = "age"; //有值
//wrapper.orderBy(StringUtils.hasText(orderBy), true, orderBy); //正序
wrapper.orderBy(StringUtils.hasText(orderBy), false, orderBy); //倒序
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行完SQL
-- 有值,正序
-- SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC
-- 有值,倒序
SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age DESC
比较运算符-allEq
重载方法有6个,功能由传入的参数决定
用法:全等,所有条件必须相当,条件使用Map<String, Object>封装, key:条件列, value:条件值
需求:查询name=zhangsan,age=18的员工信息
allEq(Map<String, V> params)
@Test
public void testQuery3() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("name", "zhangsan");
map.put("age", 18);
wrapper.allEq(map);
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
allEq(Map<String, V> params, boolean null2IsNull)
null2IsNull:如果params参数中,有某个key,它value值为null,要不要拼接这个key作为条件,true:表示使用is null 拼接, false:不拼接
@Test
public void testQuery3_1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("name", "zhangsan");
map.put("age", null); //value值为null
//wrapper.allEq(map, true); //拼接
wrapper.allEq(map, false); //不拼接
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
-- true 拼接
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name is null AND age = ?)
-- false 不拼接
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ?)
allEq(BiPredicate<String, V> filter, Map<String, V> params)
filter:判断型函数接口,用于过滤params中的条件,接口有个test方法,传2个参数:params中的key值, value
需求:查询满足指定params条件的员工数据,附加条件, 如果params的key长度小于4,不参与sql条件查询
@Test
public void testQuery3_2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("name", "zhangsan");
map.put("age", 18);
wrapper.allEq((key, value)->{
return key.length() > 4;
}, map);
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ?)
params参数key值有age, 跟name, 函数接口做了限制,key长度必须大于4, 所有age被排除,符合要求只有name这个条件。sql值拼接name条件
allEq(boolean condition, Map<String, V> params, boolean null2IsNull)
condition:allEq控制开关, 当condition为true,执行allEq语法,拼接查询条件, 为false, 不执行。
allEq(boolean condition, BiPredicate<String, V> filter, Map<String, V> params, boolean null2IsNull);
跟上面介绍重复了,同理可得即可。
比较运算符-eq
重载方法有2个
用法:等值条件过滤, sql:where 列 = 值
eq(String column, Object value):等值匹配
需求:查询name=zhangsan的员工信息
@Test
public void testQuery4_1() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name", "zhangsan");
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ?)
eq(boolean condition, String column, Object value):带开关的等值匹配
带开关的eq 操作, 使用跟上面操作一样
比较运算符-ne
重载方法有2个
用法:不等条件过滤, sql: where 列 <> 值
ne(String column, Object value):不等值匹配
需求: 查询name != zhangsan的用户信息
@Test
public void testQuery4_2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.ne("name", "zhangsan");
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name <> ?)
ne(boolean condition, String column, Object value):带开关的不等值匹配
带开关的ne 操作, 使用跟上面操作一样
比较运算符-gt/ge
gt有2个重载方法, ge也有2个重载方法
用法gt : great than 大于, sql: where 列 > 值
用法ge:greate than and equals, 大于等于, sql: where 列 >= 值
gt(String column, Obejct value) / ge(String column, Obejct value):大于/大于等于比较
需求:查询 age 大于 18 的员工信息
需求:查询age 大于等于 18 的员工信息
@Test
public void testQuery4_3() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18); //大于 18
//wrapper.ge("age", 18); //大于等于18
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
-- gt
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age > ?)
-- ge
-- SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age >= ?)
gt(boolean condition, String column, Obejct value) / ge(boolean condition, String column, Obejct value):带开关的大于/大于等于比较
带开关的gt/ ge 操作, 使用跟上面操作一样
比较运算符-lt/le
lt有2个重载方法, le也有2个重载方法
用法lt : less than 小于, sql: where 列 < 值
用法le:less than and equals, 小于等于, sql: where 列 <= 值
lt(String column, Obejct value) / le(String column, Obejct value):小于/小于等于比较
需求:查询 age 小于 18 的员工信息
需求:查询age 小于等于 18 的员工信息
@Test
public void testQuery4_4() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.lt("age", 18); //小于 18
//wrapper.le("age", 18); //小于等于18
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
-- lt
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age < ?)
-- le
-- SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age <= ?)
lt(boolean condition, String column, Obejct value) / le(boolean condition, String column, Obejct value):带开关的小于/小于等于比较
带开关的lt/ le 操作, 使用跟上面操作一样
比较运算符-isNull/isNotNull
isNull 重载2个方法, isNotNull重载2个方法
用法isNull : 列判null条件, sql: where 列 is null
用法isNotNull:列判定不为null条件, sql: where 列 is not null
isNull(String column, Obejct value) / isNotNull(String column, Obejct value):列是否为null/不为null判断
需求:查询 dept_id 为null 的员工信息
需求:查询 dept_id 不为null 的员工信息
@Test
public void testQuery4() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.isNull("dept_id"); // 为null
//wrapper.isNotNull("dept_id"); // 不为null
List<Employee> list = employeeMapper.selectList(wrapper);
System.out.println(list);
}
执行后SQL
-- is null
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id is null)
-- is not null
-- SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id is not null)
isNull(boolean condition, String column, Obejct value) / isNotNull(Boolean condition, String column, Obejct value):带开关的列是否为null/不为null判断
带开关的null/ isNotNull 操作, 使用跟上面操作一样
比较运算符-in/notIn
in重载4个方法, notIn重载4个方法
用法in: 列在指定列表数据中, sql: where 列 in (值1,值2,值3.....)
用法notIn: 列不在指定列表数据中, sql: where 列 not in (值1,值2,值3.....)
in(String column, Obejct...value) / notIn(String column, Obejct... value):可变参数方式
需求:查询 id = 1 或者 id = 2 或者 id = 3 的员工信息
需求:查询 id != 1 或者 id != 2 或者 id != 3 的员工信息
@Test
public void testQuery5() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.in("id",1L, 2L, 3L); // in
//wrapper.notIn("id",1L, 2L, 3L); //not in
List<Employee> list = employeeMapper.selectList(wrapper);
}
执行后SQL
-- in
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (?,?,?))
-- not in
-- SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (?,?,?))
in(String column, Collection<?> coll) / notIn(String column, Collection<?> coll):集合的方式
@Test
public void testQuery5() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.in("id", Arrays.asList(1L, 2L, 3L)); //in
//wrapper.notIn("id",Arrays.asList(1L, 2L, 3L)); //not in
List<Employee> list = employeeMapper.selectList(wrapper);
}
执行后SQL
跟上面操作一模一样
in(boolean condition, String column, Obejct...value) / notIn(boolean condition, String column, Obejct... value):可变参数方式
in(boolean condition, String column, Collection<?> coll) / notIn(boolean condition, String column, Collection<?> coll):数组的方式
带开关的in/ notIn 操作, 使用跟上面操作一样
比较运算符-inSql/notInSql
inSql重载2个方法, notInSql重载2个方法
用法inSql: 列在指定列表数据中, sql: where 列 in (值1,值2,值3.....)
用法notInSql: 列不在指定列表数据中, sql: where 列 not in (值1,值2,值3.....)
inSql(String column,String value) / notInSql(String column, String value)
跟之前in /notIn 方法的区别是,方法参数value是一个sql片段
需求:查询 id = 1 或者 id = 2 或者 id = 3 的员工信息
需求:查询 id != 1 或者 id != 2 或者 id != 3 的员工信息
@Test
public void testQuery5() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.inSql("id","1, 2, 3"); // in,value是sql片段
//wrapper.notInSql("id","1, 2, 3"); //not in
List<Employee> list = employeeMapper.selectList(wrapper);
}
执行后SQL
-- in sql
SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (1,2,3))
-- not in sql
-- SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (1,2,3))
inSql(boolean condition, String column, String value) / notInSql(boolean condition, String column, String value)
带开关的inSql/ notInSql 操作, 使用跟上面操作一样