第二章 条件构造器
文章目录
一、继承关系
- Wrapper:
条件构造抽象类,最顶端父类 - AbstractWrapper:
用于生成 SQL 的 WHERE 条件,entity 属性也用于生成 SQL 的 WHERE 条件
注意:entity 生成的 WHERE 条件与使用各个 api 生成的 WHERE 条件没有任何关联行为 - QueryWrapper:
entity 对象封装操作类
继承自 AbstractWrapper,自身的内部属性 entity 也用于生成 WHERE 条件 - UpdateWrapper:
Update 条件封装,用于 entity 对象的更新操作
继承自 AbstractWrapper,自身的内部属性 entity 也用于生成 WHERE 条件
二、SQL 拼接方法
1.AbstractWrapper 定义
- eq
eq(R column, Object val)
//等于 =
//例:eq("name", "Sisyphus") ---> name = '老王'
- allEq
allEq(Map<R, V> params)
//Map 内 KV 全 eq
//例:allEq({id:1, name:"Sisyphus", age:null}) ---> id = 1 and name = 'Sisyphus' and age is null
- ne
ne(R column, Object val)
//不等于 <>
//例:ne("name", "Sisyphus") ---> name <> 'Sisyphus'
- gt
gt(R column, Object val)
//大于 >
//例:get("age", 20) ---> age > 20
- ge
ge(R column, Object val)
//大于等于 >=
//例:ge("age", 18) ---> age >= 18
- lt
lt(R column, Object val)
//小于 <
//例:lt("age", 20) ---> age < 18
- le
le(R column, Object val)
//小于等于 <=
//例:le("age", 20) ---> age <= 20
- between
between(R column, Object val1, Object val2)
//BETWEEN val1 AND val2
//例:between("age", 18, 21) ---> age between 18 and 21
- notBetween
notBetween(R column, Object val1, Object val2)
//NOT BETWEEN val1 AND val2
//例:notBetween("age", 18, 21) ---> age not between 18 and 21
- like
like(R column, Object val)
//LIKE '%val%'
//例:like("name", "科技") ---> name like '%科技%'
- notLike
notLike(R column, Object val)
//NOT LIKE '%val%'
//例:notLike("name", "科技") ---> name not like '%科技%'
- likeLeft
likeLeft(R column, Object val)
//LIKE '%值'
//例:likeLeft("name", "科技大学") ---> name like '%科技大学'
- likeRight
likeRight(R column, Object val)
//LIKE '值%'
//例:likeRight("name", "江苏科技") ---> name like "江苏科技%"
- isNull
isNull(R column)
//字段 IS NULL
//例:isNull("name") ---> name is null
- isNotNull
isNotNull(R column)
//字段 IS NOT NULL
//例:isNotNull("name") ---> name is not null
- in
in(R column, Collection<?> value)
//字段 IN(value.get(0), value.get(1), ...)
//例:in("age", {18,19,20,21}) ---> age in (18,19,20,21)
- notIn
notIn(R column, Collection<?> value)
//字段 NOT IN (value.get(0), value.get(1), ...)
//例:notIn("age", {18,19,20,21}) ---> age not in (18,19,20,21)
- groupBy
groupBy(R,... columns)
//分组:GROUP BY R,...
//例:groupBy("id", "name") ---> group by id, name
- orderByAsc
orderByAsc(R,... columns)
//排序:ORDER BY R,... ASC
//例:orderByAsc("id", "name") ---> order by id ASC, name ASC
- orderByDesc
orderByDesc(R,... columns)
//排序:ORDER BY R,... DESC
//例:orderByDesc("id", "name") ---> order by id DESC, name DESC
- orderBy
orderBy(boolean condition, boolean isAsc, R,... columns)
//排序:ORDER BY R,...
//例:orderBy(true, true, "id", "name") ---> order by id ASC, name ASC
//boolean condition 表示该条件是否加入最后生成的 SQL 中
//也就是说会先依据其它条件拼接出半成品 SQL,最后再判断是否拼接此条,condition 为 true 则拼接
//除了下面出现的 select 和 setSql 之外,所有 SQL 拼接方法的第一个参数都可以选择设置 condition
//只是 orderBy 强制传参
- having
having(String sqlHaving, Object,... params)
//HAVING(SQL 语句)
//having("sum(age) > {0}", 10) ---> having sum(age) > 10
//下面的写法也是可以的
//having("sum(age) > 10") ---> having sum(age) > 10
- func
func(Consumer<Children> consumer)
//func 方法,主要方便在出现 if...else 下调用不同方法能不断链
//例:func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)})
- or
or()
//主动调用 or 表示紧接着下一个方法不是用 and 连接,不调用则默认为使用 and 连接
//拼接 OR
//例:eq("id", 1).or().eq("name", "Sisyphus") ---> id = 1 or name = 'Sisyphus'
//OR 嵌套
//例:or(i -> i.eq("name", "Sisyphus").ne("status", "在线")) ---> or (name = "Sisyphus" and status <> '在线')
- and
and(Consumer<Param>)
//AND 嵌套
//例:and(i -> i.eq("name", "Sisyphus").ne("status", "在线")) ---> and (name = 'Sisyphus' and status <> '在线')
- nested
nested(Consumer<Param> consumer)
//正常嵌套 不带 AND 或者 OR
//例:nested(i -> i.eq("name", "Sisyphus").ne("status", "在线")) ---> (name = "Sisyphus" and status <> '活着')
- apply
apply(String applySql, Object,... params)
//拼接 SQL
//apply("id = 1") ---> id = 1
//这样写不会报错,但会有 SQL 注入的风险,因此应该像下面这样写
//apply("id = {0}", 1) ---> id = 1
- last
last(String lastSql)
//无视优化规则直接拼接到 SQL 的最后
//注意:只能调用一次,多次调用则以最后一次为准,因此会有 SQL 注入风险
- exists
exists(String existsSql)
//拼接 EXISTS(SQL 语句)
//例:exists("select id from table where age = 1") ---> exists(select id from table where age = 1)
//SQL 中 EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False
- notExists
notExists(String notExistsSql)
//拼接 NOT EXISTS(SQL 语句)
//例:notExists("select id from table where age = 1") ---> not exists(select id from table where age = 1)
//SQL 中 EXISTS 可以与 NOT 一同使用,查找出不符合查询语句的记录
2.QueryWrapper 定义
- select
select(String,... sqlSelect)
//设置查询字段
//例:select("id", "name", "age") ---> select id,name,age from
3.UpdateWrapper 定义
- set
set(String column, Object val)
//SQL SET 字段
//例:set("name", "Sisyphus") ---> set name = "Sisyphus"
//例:set("name", "") ---> set name = ""
//例:set("name", null) ---> set name = null
- setSql
setSql(String sql)
//设置 SET 部分 SQL
//例:setSql("name = 'Sisyphus'") ---> set name = 'Sisyphus'
三、使用条件构造器完成查询
以第一章的项目为基础,记得先看第一章
1.StudentServiceImpl.java
//查(Wrapper)
public List<Student> queryByIdWrapper(Integer id){
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper
.select("id","name","email","age")
.eq("id",id);
return studentMapper.selectList(queryWrapper);
}
//改(Wrapper)
public boolean updateByIdWrapper(Student entity){
UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
updateWrapper
.set("name",entity.getName())
.set("email",entity.getEmail())
.set("age",entity.getAge())
.eq("id",entity.getId());
return studentMapper.update(entity,updateWrapper) > 0;
}
2.StudentController.java
//IService<> 接口里没有我们自定义的方法,因此要声明为我们自己的 Service 实现类
@Autowired
private StudentServiceImpl studentService;
@RequestMapping("queryWrapper")
public List<Student> queryByIdWrapper(@RequestParam("id") Integer id){
return studentService.queryByIdWrapper(id);
}
@RequestMapping("updateWrapper")
public void updateWrapper(@RequestParam("id") Integer id, @RequestParam("name") String name, @RequestParam("email") String email, @RequestParam("age") Integer age){
Student student = new Student();
student.setId(id);
student.setName(name);
student.setEmail(email);
student.setAge(age);
studentService.updateByIdWrapper(student);
}