MybatisPlus总结一在这:
MybatisPlus总结1/2-CSDN博客
六、分页查询:
6.1.介绍:
MybatisPlus内置了分页插件,所以我们只需要配置一个分页拦截器就可以了,由于不同的数据库的分页的方式不一样,例如mysql和oracle数据库的写法是完全不一样的,所以我们需要去指定一个数据库的类型。例如在mysql里面我们有一个limit参数,通过它来控制分页。
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//这里可以添加n个拦截器,等下我们还要添加分页拦截器:
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
6.2.代码举例:
①、Page的泛型当中传的是参与分页的表对应的实体类;
②、分页功能已经帮我们过滤掉了逻辑已删除的数据;
@SpringBootTest
public class TestPlus {
@Autowired
private UserMapper userMapper;
@Test
public void test01(){
//两个参数——当前页页码,每页信息条数:
Page<User> page = new Page<>(2,4); //long current,long size
userMapper.selectPage(page,null);//第二个参数是wrapper 条件构造器
System.out.println("逻辑未删除的总数据条数:----"+page.getTotal());
System.out.println("总共有多少页数据:---"+page.getPages());
System.out.println("每页最多展示多少条数据pageSize:---"+page.getSize());
System.out.println("当前是第几页,页码从1开始:---"+page.getCurrent());
//获取当前页数据:
List<User> users = page.getRecords();
users.forEach(user-> System.out.println(user));
System.out.println("是否有下一页:---"+page.hasNext());
System.out.println("否有上一页:---"+page.hasPrevious());
}
}
==> Preparing: SELECT COUNT(*) AS total FROM user WHERE deleted = 0
==> Parameters:
<== Columns: total
<== Row: 12
<== Total: 1
==> Preparing: SELECT id,name,email,age,deleted,version,balance FROM user WHERE deleted=0 LIMIT ?,?
==> Parameters: 4(Long), 4(Long)
<== Columns: id, name, email, age, deleted, version, balance
<== Row: 1, 张三, qq.com, 23, 0, 3, 130
<== Row: 2, 李四, lisi@qq.com, 18, 0, 1, 100
<== Row: 3, 王五, wangwu@qq.com, 18, 0, 1, 100
<== Row: 4, 赵六, zhaoliu@qq.com, 18, 0, 1, 100
<== Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5ed31735]
逻辑未删除的总数据条数:----12
总共有多少页数据:---3
每页最多展示多少条数据pageSize:---4
当前是第几页,页码从1开始:---2
User(id=1, name=张三, email=qq.com, age=23, status=null, deleted=0, version=3, balance=130)
User(id=2, name=李四, email=lisi@qq.com, age=18, status=null, deleted=0, version=1, balance=100)
User(id=3, name=王五, email=wangwu@qq.com, age=18, status=null, deleted=0, version=1, balance=100)
User(id=4, name=赵六, email=zhaoliu@qq.com, age=18, status=null, deleted=0, version=1, balance=100)
是否有下一页:---true
否有上一页:---true
SELECT * FROM users LIMIT ?,?
- 第一个占位符代表的是从第几条数据开始,数据下标从0开始的,
- 第N页: 从第(N-1)*pageSize 条数据开始查询。
- 第二个占位符表示要取出多少条数据、也就是每页的大小pageSize ;
七、条件构造器:
7.1.条件构造器的作用:
将写在where语句后面的那些条件封装成了条件构造器,目的是写出更复杂的查询条件
7.2.继承结构:
AbstractWrapper:用于条件查询封装,生成sql的where条件
- QueryWrapper:查询条件封装
- UpdateWrapper:Update条件封装
- AbstractLambdaWrapper:使用lambda语法
AbstractLambdaWrapper
- LambdaQueryWrapper:用于lambda语法使用的查询Wrapper
- LambdaUpdateWrapper:lambda更新封装Wrapper
八、QueryWrapper举例:
例1、查询所有用户:
//通过条件构造器查询一个list集合,若没有条件则可以设置null(相当于查询所有)
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
例2、转义字符:
- >:gt
- <:lt
- =:eq
- >=:ge
- <=:le
- != :ne
代码:
查找出name为李四的所有用户:
@Test
public void test02(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","李四");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
例3、模糊查询:like、notLike
- like:表示a左右都有%
- likeleft:表示a左边有%
- likeright:表示a右边有%
不建议大家使用前后模糊。因为前后模糊的话,它的效率非常低,它用不上索引,你右模糊,还能用上索引。如果你是左模糊或者是前后都模糊,它的索引效率很低的,除非你的数据量特别特别的小。
代码:
找出年龄大于15岁,姓李的用户,并且按照年龄大小升序:
@Test
public void test03(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age",15);
queryWrapper.likeRight("name","李");
queryWrapper.orderByAsc("age");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
例4、in查询:
@Test
public void test04(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id","1","2","3","4");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
例5、根据条件构造器查询多用户:
like、between、isNull、isNotNull:
@Test
public void test04(){
//user内的属性最终会以and形式拼接,对象形式: 找出年龄为18岁的用户
User user = new User();
user.setAge(18);
QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
//查询用户名包含a,年龄在20-30之间,邮箱信息不为null的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//queryWrapper可以实现链式加载
queryWrapper.like("name", "a").between("age", 20, 30).isNotNull("email");
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
例6、多种排序条件:
//查询id>2的用户,按照年龄降序排序,若年两相同则按照id升序排序
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("id", 2).orderByDesc("age").orderByAsc("id");
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
例7、查询多个字段:
//查询用户名、年龄、邮箱信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// SELECT name,age,email FROM user WHERE deleted=0:
queryWrapper.select("name","age","email");
List<User> uesrs = userMapper.selectList(queryWrapper);
System.out.println(uesrs );
//查询出来一个以map为泛型的list集合
//查询用户名、年龄、邮箱信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("name","age","email");
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
System.out.println(maps);
例8、 条件的优先级:
将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息进行修改:
//将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息进行修改
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//lambda中的条件优先执行(i就表示条件构造器)
queryWrapper.like("name", "a").and(i-> i.gt("age", 20).or().isNull("email"));
User user = new User();
user.setName("red").setEmail("test@cj.com");
int i = userMapper.update(user, queryWrapper);
System.out.println(i);
这段代码使用了 MyBatis-Plus 的 QueryWrapper 对象来构建查询条件,并且嵌套了一个 lambda 表达式。让我来解释一下这段代码的含义:
.and()
:这个方法用于指定一个 "AND" 关系,它会将前后两个条件组合在一起,要求它们同时成立。
i -> i.gt("age", 20).or().isNull("email")
:这是一个 Lambda 表达式,它定义了一个条件。这里的i
是一个占位符,代表了内部条件的 QueryWrapper 对象。
i.gt("age", 20)
:这是一个条件,它表示年龄大于 20。.or()
:这个方法用于指定一个 "OR" 关系,它会将前后两个条件组合在一起,要求它们之一成立。.isNull("email")
:这是一个条件,它表示邮箱为空。综合起来,
.and(i -> i.gt("age", 20).or().isNull("email"))
的含义是指定了一个条件,要求年龄大于 20,并且邮箱为空,它们之间的关系是 "AND",即同时成立。
例9、组装子查询:
//select * from user where id in(select id from user where id<=100)
//查询id<=100的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from user where id<=100");
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
例10、QueryWrapper实现修改操作&条件优先级:
将用户名中包含a并且(年龄大于20或邮箱为null)的用户:
//将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息进行修改
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//lambda中的条件优先执行(i就表示条件构造器)
queryWrapper.like("name", "a").and(i-> i.gt("age", 20).or().isNull("email"));
User user = new User();
user.setName("red").setEmail("test@cj.com");
int i = userMapper.update(user, queryWrapper);
System.out.println(i);
(年龄大于 20,并且用户名中包含字母 "a"),或者邮箱为空:
//将年龄>20并且用户名中包含a或邮箱为null的用户进行修改(默认情况下就是and连接)
//修改条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20).like("name", "a").or().isNull("email");
User user = new User();
user.setName("lei").setEmail("test@cj.com");
int i = userMapper.update(user, queryWrapper);
System.out.println(i);
例11、使用updateWrapper实现修改功能:
//查询用户名中包含a(年龄>20或邮箱为null)的员工信息
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
//修改条件
updateWrapper.like("name", "a").and(i->i.gt("age", 20).isNull("email"));
//修改内容
updateWrapper.set("name", "lala").set("email", "www@cjc.com");
int i = userMapper.update(null, updateWrapper);
System.out.println(i);
例12、动态sql查询:
String name=null;
String age="21";
//判断字符串是否为null或空串若为返回false,不为返回true
boolean pn = StringUtils.hasLength(name);
boolean pa = StringUtils.hasLength(age);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//判断属性是否为true,为true则执行该条件,不为则忽略该条件
queryWrapper.eq(pn,"name",name).eq(pa, "age", age);
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
注意:queryWrapper.clear();为清除多余的条件,清除后queryWrapper可以继续使用
例13、条件构造器实现删除操作:
//删除邮箱地址为null的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email");
int i = userMapper.delete(queryWrapper);
System.out.println(i);
九、LambdaQueryWrapper:
作用:为了防止我们将字段名写错进而提供了一个函数式接口来访问我们实体类中的某一个属性,当我们把属性访问之后,那么他就可以自动的获取属性所对应的字段名,来当作作为条件的哪个字段。
String name="a";
Integer ageBegin=null;
Integer ageEnd=30;
//主要避免了名称写错进而提供了直接访问表达式::
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.like(StringUtils.isNotBlank(name), User::getName,name)
.ge(ageBegin!=null, User::getAge,ageBegin)
.le(ageEnd!=null, User::getAge,ageEnd);
List<User> users = userMapper.selectList(lambdaQueryWrapper);
System.out.println(users);
LambdaUpdateWrapper:
//查询用户名中包含a(年龄>20或邮箱为null)的员工信息
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
//修改条件
updateWrapper.like(User::getName, "a").and(i->i.gt(User::getAge, 20).isNull(User::getEmail));
//修改内容
updateWrapper.set(User::getName, "lala").set(User::getEmail, "www@cjc.com");
int i = userMapper.update(null, updateWrapper);
System.out.println(i);