MyBatis-plus进阶
映射
自动映射规则
- 表名和实体类名映射-》 表名user 实体类名User
- 字段名和实体类属性名映射-》字段名name 实体类属性名name
这里需要注意:User类里的 private String name; 这个name不是属性名,而是变量名。
那么什么是属性名呢?
类里面的属性对应的get方法,其方法名去掉"get"然后首字母小写对应的就是属性名,比如:
java
// 属性名是name 映射到数据库的字段是name
public String getName() {
return name;
}
// 属性名是testName 映射到数据库的字段是testName
public String getTestName() {
return name;
}
-
字段名下划线命名方式和实体类属性小驼峰命名方式映射-》
字段名 user_email 实体类属性名 userEmail
MyBatis-plus支持这种映射规则,可以通过配置来设置:
yamlmybatis-plus: configuration: # 开启下划线到驼峰命名的映射 map-underscore-to-camel-case: true
表映射@TableName注解
Pojo类通过@TableName注解指定映射的数据库表名,就会完成表名的映射。
@TableName注解主要应用在类名和数据库表名不一致的情况。
java
// 表示User类映射到t_user表
@TableName("t_user")
public class User {
private Long id;
public String getName() {
return name;
}
private String name;
private Integer age;
private String email;
}
那如果数据库表特别多的情况下,这样每个类都指定具体表名会很麻烦,此时就可以开启表映射的全局配置。
表映射的全局配置:
yaml
mybatis-plus:
global-config:
db-config:
# 全局配置表名的前缀,这样会自动将Pojo类名的首字母小,并且加上前缀t_
# 这样就不用使用@TableName来指定表名
table-prefix: t_
字段映射
当数据库字段和表实体类的属性不一致时,可以使用@TableField注解改变字段和属性的映射,让注解中的名称和表字段保持一致。
java
@TableField("user_email")
private String email;
此时的sql是:select id,user_email as email from user
有一个问题场景:当数据库表中的某个字段设置为desc时,注意:desc为数据库的关键字,此时查询的sql语句就是:
select id,name,desc from user
很明显,这样的sql执行时会报错。那么怎么解决呢?
给关键字加上分隔符就能执行成功:select id,name,`desc` from user
在Java中 给desc这个属性加上注解@TableField("`desc`") 也就是字段名加上分隔符就可以了。
字段失效
当数据库中有字段不想被查询时,可以使用@TableField(select= false)来隐藏这个字段。在拼接sql语句的时候就不会拼接这个字段
java
// 查询时不会查出Email这个字段
@TableField(select = false)
private String email;
视图属性
实际开发中,有些字段不需要数据库存储,但需要展示,像这种实体类中存在但是数据库中不存在的字段,叫做视图字段。
这种字段可以通过@TableField(exist = false)注解来去掉这个字段,不让他作为查询或DML字段。
java
@TableField(exist = false)
private String emailPhone;
条件构造器
MyBatis-plus的条件查询是基于面向对象的思想,条件查询使用对象来完成封装。
在实际开发中,只需要关注QueryWrapper和LambdaQueryWrapper这两个即可。
等值查询
eq 方法
下面的两种查询方式的结果是一样的。
java
// 使用 QueryWrapper
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 设置条件 name='test2'
wrapper.eq("name", "test2");
User user1 = userService.getOne(wrapper);
System.out.println(user1);
// 使用LambdaQueryWrapper,这种方式可以避免字段名写错
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getName, "test2");
User user2 = userService.getOne(lambdaQueryWrapper);
System.out.println(user2);
null的判断
当前端传来的查询条件为null时。此时用户希望不需要以此条件进行查询,我们就不需要进行查询拼接。
可以使用下面的方式进行判断处理:
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
String name = "test2";
// 当name为null或者""时,不作为查询拼接
lambdaQueryWrapper.eq(StringUtils.isNotBlank(name),User::getName, name);
User user2 = userService.getOne(lambdaQueryWrapper);
System.out.println(user2);
多条件查询
第一种方式:可以通过多个eq 来构建多条件查询
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
String name = "test2";
lambdaQueryWrapper.eq(User::getName, name);
lambdaQueryWrapper.eq(User::getAge, 12);
User user2 = userService.getOne(lambdaQueryWrapper);
System.out.println(user2);
此时对应的sql是select * from t_user where name='test2' and age =12
第二种方式:allEq 方法,通过将查询条件封装在一个map中,然后调用allEq方法,实现多条件查询
java
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("name", "test2");
hashMap.put("age", 12);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 第二个参数表示,当map中的值为null时,不作为查询条件进行拼接
queryWrapper.allEq(hashMap,false);
User user3 = userService.getOne(lambdaQueryWrapper);
System.out.println(user3);
ne 不等值查询
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
String name = "test2";
lambdaQueryWrapper.ne(User::getName, name);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where name <> 'test2'
范围查询
gt 大于
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.gt(User::getAge, 12);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age > 12
ge 大于等于
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.ge(User::getAge, 12);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age >= 12
lt 小于
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.lt(User::getAge, 12);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age < 12
le 小于等于
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.le(User::getAge, 12);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age <= 12
between 范围内
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 查询年龄在12-36之间
lambdaQueryWrapper.between(User::getAge, 12,36);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age between 12 and 36 查询结果包含年龄为12和36的数据。
notBetween 范围外
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 查询年龄不在12-36之间
lambdaQueryWrapper.between(User::getAge, 12,36);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age not between 12 and 36
模糊查询
like
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.like(User::getName, "张");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where name like '%张%'
notLike
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notLike(User::getName, "张");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where name not like '%张%'
likeLeft
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.likeLeft(User::getName, "张");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where name like '%张' 查询name以'张'结尾
likeRight
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.likeRight(User::getName, "张");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where name like '张%' 查询name以'张'开头
判空查询
isNull
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.isNull(User::getEmail);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where email is null
isNotNull
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.isNotNull(User::getEmail);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where email is not null
包含查询 in
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
ArrayList<Integer> arrayList = new ArrayList<>();
Collections.addAll(arrayList, 21, 22, 23);
lambdaQueryWrapper.in(User::getAge, arrayList);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age in (21,22,23)
不包含查询 notIn
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
ArrayList<Integer> arrayList = new ArrayList<>();
Collections.addAll(arrayList, 21, 22, 23);
lambdaQueryWrapper.notIn(User::getAge, arrayList);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age not in (21,22,23)
包含查询 inSql
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 查询条件直接写死
// lambdaQueryWrapper.inSql(User::getAge, "11,12,13");
// 查询条件时一条sql
lambdaQueryWrapper.inSql(User::getAge, "select age from k_user where age < 20");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
对应的sql:select * from t_user where age in (11,12,13)
select * from t_user where age in (select age from k_user where age < 20)
不包含查询 notInSql
调用方式与上面类似,这里不再举例
分组查询 groupBy
java
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 分组字段
wrapper.groupBy("age");
// 查询字段
wrapper.select("age,count(*) as field_count");
List<Map<String, Object>> mapList = userService.listMaps(wrapper);
System.out.println(mapList);
对应的sql :select age,count(*) as field_count from t_user group by age
聚合查询 having
java
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 分组字段
wrapper.groupBy("age");
// 查询字段
wrapper.select("age,count(*) as field_count");
// 聚合条件筛选
wrapper.having("field_count > 10");
List<Map<String, Object>> mapList = userService.listMaps(wrapper);
System.out.println(mapList);
对应的sql :select age,count(*) as field_count from t_user group by age having field_count > 10
排序查询
- orderByAsc 升序
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.orderByAsc(User::getAge,User::getId);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql :select * from t_user order by age asc,id asc
- orderByDesc 降序
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.orderByDesc(User::getAge,User::getId);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql :select * from t_user order by age desc,id desc
-
orderBy 有升序有降序
javaLambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); // 参数1:如果排序的字段值为null,是否还参与排序 // 参数2:是否是升序 // 参数3:排序的字段 lambdaQueryWrapper.orderBy(true,true,User::getAge); lambdaQueryWrapper.orderBy(true,false,User::getId); List<User> userList = userService.list(lambdaQueryWrapper); System.out.println(userList); // 对应的sql :select * from t_user order by age asc,id desc
内嵌逻辑查询 func
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 根据不同情况来选择拼接不同的查询条件
lambdaQueryWrapper.func(new Consumer<LambdaQueryWrapper<User>>() {
@Override
public void accept(LambdaQueryWrapper<User> userLambdaQueryWrapper) {
if (1==1){
userLambdaQueryWrapper.eq(User::getAge,22);
}else {
userLambdaQueryWrapper.ne(User::getAge,22);
}
}
});
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql:select * from t_user where age = 22
逻辑查询
-
and
正常拼接默认就是and,比如:
javaLambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); // 根据不同情况来选择拼接不同的查询条件 lambdaQueryWrapper.gt(User::getAge,12).lt(User::getAge,22); List<User> userList = userService.list(lambdaQueryWrapper); System.out.println(userList); // 对应的sql;select * from t_user where age > 12 and age < 22and的嵌套查询:
javaLambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.eq(User::getName, "张三").and(u -> u.gt(User::getAge, 22).or().lt(User::getAge, 20)); List<User> userList = userService.list(lambdaQueryWrapper); System.out.println(userList); // 对应的sql;select * from t_user where name = '张三' and (age > 22 or age < 20) -
or
javaLambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.gt(User::getAge, 22).or().lt(User::getAge, 20); List<User> userList = userService.list(lambdaQueryWrapper); System.out.println(userList); // 对应的sql;select * from t_user where age > 22 or age < 20or 的嵌套查询
javaLambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.eq(User::getName, "张三").or(u->u.gt(User::getAge,20).lt(User::getAge,30)); List<User> userList = userService.list(lambdaQueryWrapper); System.out.println(userList); // 对应的sql;select * from t_user where name = '张三' or (age > 20 and age < 30) -
nested
.nested()用于嵌套条件分组 的核心方法,作用是将一组条件用()包裹起来,形成独立的条件块,避免多个条件之间的逻辑运算优先级混乱。需求:查询
age > 20且(name = "张三"或email 包含 "test")的用户。javaLambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>() .gt(User::getAge, 20) // 外层条件:age>20 .nested(qw -> qw // 嵌套分组:(name=张三 OR email包含test) .eq(User::getName, "张三") .or() .like(User::getEmail, "test") ); List<User> userList = userService.list(lambdaQueryWrapper); System.out.println(userList); // 对应的sql;select * from t_user WHERE age > 20 AND (name = '张三' OR email LIKE '%test%')
自定义查询 apply
apply方法的参数是字符串,会跟在sql语句where的后面,在复杂查询的应用场景中使用。
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.apply("id=1");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql;select * from t_user where id = 1
last 查询
last 方法允许你直接在查询的最后添加一个 SQL 片段。
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.last("limit 0,10");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql;select * from t_user limit 0,10
注意:last 方法只能调用一次,多次调用将以最后一次为准。比如:
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.last("where age =22");
lambdaQueryWrapper.last("and name = '张三'");
lambdaQueryWrapper.last("limit 0,10");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql;select * from t_user limit 0,10
exists查询
exists 方法用于在查询中添加一个 EXISTS 子查询。通过调用 exists 方法,可以将一个完整的 SQL 子查询作为 EXISTS 条件添加到主查询中。
exists表示当子查询有返回结果时才执行主查询,如果子查询没有返回结果,那么不执行主查询。
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.exists("select id from t_user where age = 1");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql;select * from t_user WHERE EXISTS (select id from t_user where age = 1)
notExists查询
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notExists("select id from t_user where age = 1");
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql;select * from t_user WHERE NOT EXISTS (select id from t_user where age = 1)
select查询
select 方法用于设置查询的字段。通过调用 select 方法,可以指定在查询结果中包含哪些字段,从而实现字段级别的查询定制。
java
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.select(User::getId, User::getName, User::getAge);
List<User> userList = userService.list(lambdaQueryWrapper);
System.out.println(userList);
// 对应的sql;select id,name,age from t_user