MyBatis Plus实战(二)条件查询
条件查询
抽象类Wrapper是所有条件构造器的父类,我们使用它的子类QueryWrapper完成条件构造。
QueryWrapper封装的方法
setSqlSelect 设置 SELECT 查询字段
where WHERE 语句,拼接 + WHERE 条件
and AND 语句,拼接 + AND 字段=值
andNew AND 语句,拼接 + AND (字段=值)
or OR 语句,拼接 + OR 字段=值
orNew OR 语句,拼接 + OR (字段=值)
eq 等于=
allEq 基于 map 内容等于=
ne 不等于<>
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=
like 模糊查询 LIKE
notLike 模糊查询 NOT LIKE
in IN 查询
notIn NOT IN 查询
isNull NULL 值查询
isNotNull IS NOT NULL
groupBy 分组 GROUP BY
having HAVING 关键词
orderBy 排序 ORDER BY
orderAsc ASC 排序 ORDER BY
orderDesc DESC 排序 ORDER BY
exists EXISTS 条件语句
notExists NOT EXISTS 条件语句
between BETWEEN 条件语句
notBetween NOT BETWEEN 条件语句
addFilter 自由拼接 SQL
last 拼接在最后,例如:last("LIMIT 1")
如果点进每一个方法查看源码发现,所有方法都调用了一个同名的方法,这个方法的第一个参数为 boolean condition,它表示该条件是否加入最后生成的sql中,如果设为false,则没有改条件。使用场景:多条件查询时,根据是否传递该属性值来决定SQL生成。
//like的源码
default Children like(R column, Object val) {
return this.like(true, column, val);
}
查询全部字段
查询用户名中有 “m”的数据
@Test
public void selectCondition1() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name", "m");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
查询姓名有“m”,年龄在0-20岁之间,上级id不为null的数据
@Test
public void selectCondition2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name", "m").between("age", 0, 20).isNotNull("manager_id");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
姓氏为"m",或者年龄大于7岁,按照年龄降序排序,年龄相同的按照id升序
@Test
public void selectCondition3() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
* like: '%值%'
* likeLeft: '%值'
* lifeRight: '值%'
*/
queryWrapper.likeRight("user_name", "m").or().ge("age", 7)
.orderBy(true, false, "age")
.orderBy(true, true, "id");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
查询姓氏为"m",并且年龄小于40且大于3
@Test
public void selectCondition4() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("user_name", "m").and(qw -> qw.lt("age", 30).gt("age", 3));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
查询部分字段
只需要id,name字段
@Test
public void selectCondition5() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id", "user_name").like("user_name", "m").lt("age", 30);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
排除email,age字段
@Test
public void selectCondition6() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select(User.class, user -> !user.getColumn().equals("age") && !user.getColumn().equals("email"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
对象实例作构造方法参数
上面使用的条件构造器中,采用的都是无参构造方法,MP允许我们传递实体对象给条件构造器,其中实体对象不为null的属性将作为where条件,默认 = 比较。实例生成的where条件与各个Api生成的where条件没有任何关联行为,都会出现在sql的where中。
@Test
public void selectCondition7() {
User user = new User();
user.setName("mike");
user.setAge(10)
QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/*
未使用其他方法:
生成Sql: where user_name = ? AND age = ?
加上条件queryWrapper.likeRight("user_name","m").gt("age",10);
生成Sql:where user_name = ? AND age = ? AND (user_name LIKE ? AND age > ?)
*/
传入对象实例默认构造的where条件是 等值 = 比较,某些场景下不符合我们的要求,此时可以使用之前提到过的@TableFiled注解,在name上标注@TableFiled(condition = SqlCondition.LIKE),来改变默认条件。改变默认条件后,生成的SQL:WHERE user_name LIKE CONCAT('%' , ? , %") AND age = ?
/**
* SQL 比较条件常量定义类
*/
public class SqlCondition {
/**
* 等于
*/
public static final String EQUAL = "%s=#{%s}";
/**
* 不等于
*/
public static final String NOT_EQUAL = "%s<>#{%s}";
/**
* % 两边 %
*/
public static final String LIKE = "%s LIKE CONCAT('%%',#{%s},'%%')";
/**
* % 左
*/
public static final String LIKE_LEFT = "%s LIKE CONCAT('%%',#{%s})";
/**
* 右 %
*/
public static final String LIKE_RIGHT = "%s LIKE CONCAT(#{%s},'%%')";
}
这里还可以自定义构造条件,不同场景不同方式,不再赘述。
更多查询方法
SelectMaps
@Test
public void selectCondition8() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
List<Map<String, Object>> users = userMapper.selectMaps(queryWrapper);
System.out.println(users);
}
使用SelectMaps看似跟SelectList没有区别,看一下打印结果:
[{create_time=2021-07-20T17:13:31, manager_id=2, name=mike, id=1, age=10, email=mikemike@qq.com},
{create_time=2021-07-20T17:41:14, name=tom, id=2, age=24, email=tomtom@qq.com},
{create_time=2021-07-19T14:15:50, manager_id=1, name=ez, id=3, age=20, email=ezez@qq.com}]
SelectMaps帮我们剔去了值为null的字段,当大量字段是null时,为了方便看数据,SelectMaps就出场了。
@Test
public void selectCondition8() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id","user_name","email");
List<Map<String, Object>> users = userMapper.selectMaps(queryWrapper);
System.out.println(users);
}
打印结果:
[{user_name=mike, id=1, email=mikemike@qq.com}, {user_name=tom, id=2, email=tomtom@qq.com}, {user_name=ez, id=3, email=ezez@qq.com}]
SelectObjs
根据Wrapper条件,查询全部记录,但只返回第一个字段的值。
@Test
public void selectCondition9() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
List<Object> objects = userMapper.selectObjs(queryWrapper);
System.out.println(objects);
}
第一个字段是id,所以打印结果:[1, 2, 3]
SelectCount
根据QuerWrapper条件查询总数
@Test
public void selectCondition10() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age",10);
Integer count = userMapper.selectCount(queryWrapper);
System.out.println(count);
}
/**
* 使用selectCount方法不能知道查询的列名
* 生成SQL:SELECT COUNT( 1 ) FROM user WHERE (age >= ?)
*/
打印结果:3 (有3条年龄大于等于10的数据)
SelectOne
根据queryWrapper条件返回一条记录,且只能返回一条或Null,否则报错。
@Test
public void selectCondition11() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "mike");
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);
}
打印结果:
User(id=1, name=mike, age=10, email=mikemike@qq.com, managerId=2, createTime=2021-07-20T17:13:31, updateTime=null, version=null, deleteId=null)
lambda条件构造器
除了上面的QueryWrapper
条件构造器,MP还提供了Lambda条件构造器,它能防止我们写错字段名称。
三种方式创建Lambda条件构造器:
LambdaQueryWrapper<User> lambdaWrapper = new QueryWrapper<User>().lambda();
LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
LambdaQueryWrapper<User> lambdaWrapper = Wrappers.lambdaQuery();
测试:
@Test
public void lamdaTest() {
LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.like(User::getName, "tom").ge(User::getAge, 10);
List<User> userList = userMapper.selectList(lambdaQueryWrapper);
userList.forEach(System.out::println);
}
打印结果:
User(id=2, name=tom, age=24, email=tomtom@qq.com, managerId=null, createTime=2021-07-20T17:41:14, updateTime=null, version=null, deleteId=null)
LambdaQueryChainWrapper
允许我们链式构造where条件和调用查询方法。
@Test
public void lambdaTest2() {
List<User> userList = new LambdaQueryChainWrapper<User>(userMapper)
.like(User::getName, "mike")
.ge(User::getAge, 10).list();
userList.forEach(System.out::println);
}
打印结果:
User(id=1, name=mike, age=10, email=mikemike@qq.com, managerId=2, createTime=2021-07-20T17:13:31, updateTime=null, version=null, deleteId=null)
查看LambdaQueryChainWrapper源码,实际上内部新创建了LambdaQueryWrapper,和分开写条件并没什么区别。
LambdaQueryChainWrapper 实现了ChainQuery
你应当热爱自由!
作者:Leejk,转载请注明原文链接:https://www.cnblogs.com/leejk/p/15040738.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)