一、条件构造器关系
条件构造器关系介绍:
绿色框:抽象类 abstract
蓝色框:正常 class 类,可 new 对象
黄色箭头:父子类关系,箭头指向为父类
wrapper介绍:
Wrapper :条件构造抽象类,最顶端父类
AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
QueryWrapper :Entity 对象封装操作类,不是用lambda语法
UpdateWrapper : Update 条件封装,用于Entity对象更新操作
AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
LambdaUpdateWrapper : Lambda 更新封装Wrapper
二、项目实例
函数名 | 说明 | 举例 |
---|---|---|
eq | 等于 = | 例:eq ( " name ", " 老叶 " ) —> name = ’ 老叶 ’ |
ne | 不等于 <> | 例:ne ( " name ", " 老叶 " ) —> name <> ’ 老叶 ’ |
gt | 大于 > | 例:gt ( " age ", 18 ) —> name > 18 |
ge | 大于等于 >= | 例:ge ( " age ", 18 ) —> name >= 18 |
lt | 小于 < | 例:lt ( " age ", 18 ) —> name < 18 |
le | 小于等于 <= | 例:le ( " age ", 18 ) —> name <= 18 |
between | Between 值1 and 值2 | 例:between ( " age ", 18, 30 ) —> age between 18 and 30 |
notBetween | NOT Between 值1 and 值2 | 例:notBetween ( " age ", 18, 30 ) —> age not between 18 and 30 |
like | LIKE ’ %值% ’ | 例:like ( " name ", " 王 " ) —> name like ’ %王% ’ |
notLike | NOT LIKE ’ %值% ’ | 例:notLike ( " name ", " 王 " ) —> name not like ’ %王% ’ |
likeLeft | LIKE ’ %值 ’ | 例:likeLeft ( " name ", " 王 " ) —> name like ’ %王 ’ |
likeRight | LIKE ’ 值% ’ | 例:likeRight ( " name ", " 王 " ) —> name like ’ 王% ’ |
isNull | 字段 IS NULL | 例:isNull ( " name " ) —> name is null |
isNotNull | 字段 IS NOT NULL | 例:isNotNull ( " name " ) —> name is not null |
in | 字段 IN (v0, v1, …) | 例:in ( " age ", {1, 2, …} ) —> age in (1, 2, …) |
notIn | 字段 NOT IN (v0, v1, …) | 例:notIn ( " age ", {1, 2, …} ) —> age not in (1, 2, …) |
inSql | 字段 IN ( sql语句 ) | inSql ( " id ", " select id from table where id < 3 " ) —> id in ( select id from table where id < 3 ) |
notInSql | 字段 NOT IN ( sql语句 ) | notInSql ( " id ", " select id from table where id < 3 " ) —> id not in ( select id from table where id < 3 ) |
groupBy | 分组:GROUP BY 字段, … | 例:groupBy ( " id ", " name " ) —> group by id, name |
orderBy | 排序:ORDER BY 字段, … | 例:orderBy ( " id ", " name " ) —> order by id ASC, name DESC |
orderByAsc | 排序:ORDER BY 字段, … ASC | 例:orderByAsc ( " id ", " name " ) —> order by id ASC, name ASC |
orderByDesc | 排序:ORDER BY 字段, … DESC | 例:orderByDesc ( " id ", " name " ) —> order by id DESC, name DESC |
having | HAVING ( sql语句 ) | 例:having ( " sum ( age ) > { 0 } ", 11 ) —>having sum ( age ) > 11 |
or | 拼接 OR | 注意事项: 主动调用 or 表示紧接着下一个方法不是用 and 连接!(不调用 or 则默认为使用 and 连接) 例:eq ( " id ", 1 ).or ().eq ( " name ", " 老王 " ) —> id = 1 or name = ’ 老王 ’ |
and | 嵌套 AND | 例:and ( i -> i.eq ( " name ", " 李白 " ).ne ( " status ", " 活着 " ) ) —> and ( name = ’ 李白 ’ and status <> ’ 活着 ’ ) |
nested | 正常嵌套,不带 AND 或者 OR | 例:nested ( i -> i.eq ( " name ", " 李白 " ).ne ( " status ", " 活着 " ) ) —> ( name = ’ 李白 ’ and status <> ’ 活着 ’ ) |
apply | 拼接 sql | 注意事项: 该方法可用于数据库函数 动态入参的 params 对应前面 sqlHaving 内部的 { index } 部分,这样是不会有 sql 注入风险的,反之会有! 例:apply ( " date_format ( dateColum, ’ %Y-%m-%d ’ ) = { 0 } ", " 2023-10-30 " ) —> date_format ( dateColumn, ’ %Y-%m-%d ’ ) = ’ 2023-10-30 ’ |
last | 无视优化规则直接拼接到 sql 的最后 | 注意事项: 只能调用一次,多次调用以最后一次为准。有 sql 注入的风险,请谨慎使用 例:last ( " limit 1 " ) |
exists | 拼接 EXISTS ( sql语句 ) | 例:exists ( " select id from table where age = 1 " ) —> exists ( select id from table where age = 1 ) |
notExists | 拼接 NOT EXISTS ( sql语句 ) | 例:notExists ( " select id from table where age = 1 " ) —> not exists ( select id from table where age = 1 ) |
1、根据简单条件查询
/*** 通过单个ID主键进行查询*/@Testpublic void selectById() {User user = userMapper.selectById(1094592041087729666L);System.out.println(user);}/*** 通过多个ID主键查询*/@Testpublic void selectByList() {List<Long> longs = Arrays.asList(1094592041087729666L, 1094590409767661570L);List<User> users = userMapper.selectBatchIds(longs);users.forEach(System.out::println);}/*** 通过Map参数进行查询*/@Testpublic void selectByMap() {Map<String, Object> params = new HashMap<>();params.put("name", "郑梓妍");params.put("age", 18);List<User> users = userMapper.selectByMap(params);users.forEach(System.out::println);}
2、Wrapper 条件构造器
MyBatis Plus 还提供了 Wrapper 条件构造器,具体使用请看如下代码:
/*** 名字包含雨* 且年龄小于40* <p>* WHERE name LIKE '%雨%' AND age < 40*/@Testpublic void selectByWrapperOne() {QueryWrapper<User> wrapper = new QueryWrapper();wrapper.like("name", "雨").lt("age", 40);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 名字包含雨* 且年龄大于20小于40* 且邮箱不能为空* <p>* WHERE name LIKE '%雨%' AND age BETWEEN 20 AND 40 AND email IS NOT NULL*/@Testpublic void selectByWrapperTwo() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.like("name", "雨").between("age", 20, 40).isNotNull("email");List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 名字为王姓* 或者年龄大于等于25* 按照年龄降序排序,年龄相同按照id升序排序* <p>* WHERE name LIKE '王%' OR age >= 25 ORDER BY age DESC , id ASC*/@Testpublic void selectByWrapperThree() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.likeRight("name", "王").or().ge("age", 25).orderByDesc("age").orderByAsc("id");List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 查询创建时间为2019年2月14* 且上级领导姓王* <p>* WHERE date_format(create_time,'%Y-%m-%d') = '2019-02-14' AND manager_id IN (select id from user where name like '王%')*/@Testpublic void selectByWrapperFour() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.apply("date_format(create_time,'%Y-%m-%d') = {0}", "2019-02-14").inSql("manager_id", "select id from user where name like '王%'");List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 查询王姓* 且年龄小于40或者邮箱不为空* <p>* WHERE name LIKE '王%' AND ( age < 40 OR email IS NOT NULL )*/@Testpublic void selectByWrapperFive() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.likeRight("name", "王").and(qw -> qw.lt("age", 40).or().isNotNull("email"));List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 查询王姓* 且年龄大于20 、年龄小于40、邮箱不能为空* <p>* WHERE name LIKE ? OR ( age BETWEEN ? AND ? AND email IS NOT NULL )*/@Testpublic void selectByWrapperSix() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.likeRight("name", "王").or(qw -> qw.between("age", 20, 40).isNotNull("email"));List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** (年龄小于40或者邮箱不为空) 并且名字姓王* WHERE ( age < 40 OR email IS NOT NULL ) AND name LIKE '王%'*/@Testpublic void selectByWrapperSeven() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.nested(qw -> qw.lt("age", 40).or().isNotNull("email")).likeRight("name", "王");List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 查询年龄为30、31、32* WHERE age IN (?,?,?)*/@Testpublic void selectByWrapperEight() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.in("age", Arrays.asList(30, 31, 32));List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 年龄为30、31、32* 查询一条数据* limit 1*/@Testpublic void selectByWrapperNine() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.in("age", Arrays.asList(30, 31, 32)).last("limit 1");List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}
三、具体使用操作
注意:以下条件构造器的方法入参中的 column 均表示数据库字段
1、ge、gt、le、lt、isNull、isNotNull
@Test
public void testDelete() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.isNull("name").ge("age", 12).isNotNull("email");int result = userMapper.delete(queryWrapper);System.out.println("delete return count = " + result);
}
update user set deleted = 1 where deleted = 0 and name is null and age >= ? and email is not null
2、eq、ne
selectOne 返回的是一条实体记录,当出现多条时会报错
@Test
public void testSelectOne() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "Tom");User user = userMapper.selectOne(queryWrapper);System.out.println(user);
}
3、between、notBetween
包含大小边界
@Test
public void testSelectCount() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.between("age", 20, 30);Integer count = userMapper.selectCount(queryWrapper);System.out.println(count);
}
select count(1) from user where deleted = 0 and age Between 20 and 30
4、allEq
包含大小边界
@Test
public void testSelectList() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();Map<String, Object> map = new HashMap<>();map.put("id", 2);map.put("name", "Jack");map.put("age", 20);queryWrapper.allEq(map);List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
}
select id, name, age, email, create_time, update_time, deleted, version from user where deleted = 0 and name = 'Jack' and id = 2 and age = 20
5、like、notLike、likeLeft、likeRight
selectMaps 返回 Map 集合列表
@Test
public void testSelectMaps() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.notLike("name", "e").likeRight("email", "t");List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表maps.forEach(System.out::println);
}
select id, name, age, email, create_time, update_time, deleted, version from user where deleted = 0 and name not like '%e%' and email like 't%'
6、in、notIn、inSql、notInSql、exists、notExists
in、notIn:
notIn("age", {1,2,3}) ---> age not in (1,2,3)notIn("age", 1, 2, 3) ---> age not in (1,2,3)
inSql、notInSql:可以实现子查询
inSql("age", "1,2,3") ---> age in (1,2,3)inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3)
@Test
public void testSelectObjs() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//queryWrapper.in("id", 1, 2, 3);queryWrapper.inSql("id", "select id from user where id < 3");List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表objects.forEach(System.out::println);
}
select id, name, age, email, create_time, update_time, deleted, version from user where deleted = 0 and id in (select id from user where id < 3)
7、or、and
这里使用的是 UpdateWrapper 不调用 or 则默认为使用 and 连接
@Test
public void testUpdate() {//修改值User user = new User();user.setAge(99);user.setName("Andy");//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").or().between("age", 20, 30);int result = userMapper.update(user, userUpdateWrapper);System.out.println(result);
}
update user set name = 'Andy', age = 99, update_time = ? where deleted = 0 and ((name like '%h%') or (age between 20 and 30))-- 名称包含’h‘,或名年龄在20到30岁之间
8、嵌套or、嵌套and
这里使用 lambda 表达式,or 中的表达式最后翻译成 sql 时会被加上圆括号
@Test
public void testUpdate2() {//修改值User user = new User();user.setAge(99);user.setName("Andy");//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").or(i -> i.eq("name", "李白").ne("age", 20));int result = userMapper.update(user, userUpdateWrapper);System.out.println(result);
}
update user set name = 'Andy', age = 99, update_time = ? where deleted = 0 and name like '%h%' or (name = '%李白%' and age <> 20)-- 名称包含’h‘,或名称包含‘李白’且年龄不等于20岁
9、orderBy、orderByDesc、orderByAsc
@Test
public void testSelectListOrderBy() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("id");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
}
select id, name, age, email, create_time, update_time, deleted, version from user where deleted = 0 order by id desc
10、last
直接拼接到 sql 的最后
注意:只能调用一次,多次调用以最后一次为准,有 sql 注入的风险,请谨慎使用
@Test
public void testSelectListLast() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.last("limit 1");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
}
select id, name, age, email, create_time, update_time, deleted, version from user where deleted = 0 limit 1
11、指定要查询的列
@Test
public void testSelectListColumn() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("id", "name", "age");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
}
select id, name, age from user where deleted = 0
12、set、setSql
最终的 sql 会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中的字段
@Test
public void testUpdateSet() {//修改值User user = new User();user.setAge(99);//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").set("name", "老李头") //除了可以查询还可以使用set设置修改的字段.setSql(" email = '123@qq.com'"); //可以有子查询int result = userMapper.update(user, userUpdateWrapper);
}
update user set age = 99, update_time = ?, name = '老李头', email = '123@qq.com' where deleted = 0 and name like '%h%'
四、项目中的实际应用
实例1-- 包含 eq 相等的比较方法
实例2-- 包含 ge le 等比较方法;及分页查询
好事定律:每件事最后都会是好事,如果不是好事,说明还没到最后。