MybatisPlusMP的分页查询多条件查询以及查询过程中解决null的空值判定
Posted 懒羊羊.java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MybatisPlusMP的分页查询多条件查询以及查询过程中解决null的空值判定相关的知识,希望对你有一定的参考价值。
文章目录
前言
MP这样一款强大的持久层框架处理起来复杂的SQL来也是得心应手,效率极高,快快与我一同领略Plus的独特魅力吧
一.分页处理
1.调用方法传入参数获取返回值
创建IPage分页对象,设置分页参数,1为当前页码,3为每页显示的记录数,执行分页查询并获取其结果
@SpringBootTest
class Mybatisplus
@Autowired
private UserDao userDao;
//分页查询
@Test
void testSelectPage()
IPage<User> page=new Page<>(1,3);
userDao.selectPage(page,null);
System.out.println("当前页码值:"+page.getCurrent());
System.out.println("每页显示数:"+page.getSize());
System.out.println("一共多少页:"+page.getPages());
System.out.println("一共多少条数据:"+page.getTotal());
System.out.println("数据:"+page.getRecords());
2.设置分页拦截器
将MP提供的分页拦截器配置成Spring管理的bean对象
@Configuration
public class MybatisPlusConfig
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor()
//1 创建MybatisPlusInterceptor拦截器对象
MybatisPlusInterceptor mpInterceptor=new MybatisPlusInterceptor();
//2 添加分页拦截器
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mpInterceptor;
查询结果如下:
MP有多智能,他给我们提供的方法功能太强大,以至于我们只需传入两个对象即可自动完成分页查询
二.条件查询
2.1通过QueryWrapper对象来执行分页查询
@SpringBootTest
class Mybatisplus
@Autowired
private UserDao userDao;
@Test
void testGetAll()
QueryWrapper qw = new QueryWrapper();
qw.lt("age",18);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
注:lt()方法为小于(<) ,对应的SQL为:
SELECT id,name,password,age,tel FROM user WHERE (age < ?)
很容易发现,以字符串形式输出作为查询条件可能会出现字符串拼写错误,针对此种情况,可以进行一下小改进!
2.2在QueryWrapper对象的基础上使用lambda表达式
为了解决以字符串形式作为输出而造成拼写错误的问题,通过lambda来实现实体与属性对应进行查询,就极大地提高了查询的准确性
@SpringBootTest
class Mybatisplus
@Autowired
private UserDao userDao;
@Test
void testGetAll()
QueryWrapper<User> qw = new QueryWrapper<User>();
qw.lambda().lt(User::getAge, 10);//添加条件
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
与之对应的SQL语句同样也是:
SELECT id,name,password,age,tel FROM user WHERE (age < ?)
注:构建LambdaQueryWrapper的时候泛型不能省
当不使用泛型时会提示默认的Object类不是函数接口
而我们的lambda()的底层又需要传进去一个实体,传进去Object显然不能与后面的查询条件相联系!
此时我们再次编写条件的时候,就不会存在写错名称的情况,但是qw后面多了一层lambda()调用
2.3直接通过LambdaQueryWrapper对象
这也是方式二的另一种写法,原理相同都是利用LambdaQueryWrapper
@SpringBootTest
class Mybatisplus
@Autowired
private UserDao userDao;
@Test
void testGetAll()
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
三.多条件查询
对于多条件的情景,MP依然可以简单化解,并且构建多条件的时候,可以支持链式编程
3.1且的情况
场景一:查询数据库表中,年龄在3岁到8岁之间的用户信息
@SpringBootTest
class Mybatisplus
@Autowired
private UserDao userDao;
@Test
/**
* 多条件查询
*/
void testGetAll04() //方式四 (常用!)
LambdaQueryWrapper<Users> qw4 = new LambdaQueryWrapper<>();
qw4.lt(Users::getAge, 8); //上限
qw4.gt(Users::getAge, 3); //下限
// qw4.lt(Users::getAge, 8).gt(Users::getAge, 3); 链式编程!
List<Users> users = userDao.selectList(qw4);
System.out.println(users);
注:gt(),大于(>),最终的SQL语句为
SELECT id,name,password,age,tel FROM user WHERE (age < ? AND age > ?)
也是迅速查出来了结果
3.2或的情况
场景二:查询数据库表中,年龄小于3或年龄大于8的数据
@SpringBootTest
class Mybatisplus
@Autowired
private UserDao userDao;
@Test
void testGetAll()
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(User::getAge, 3).or().gt(User::getAge, 8);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
这里的or()就相当于sql语句中的or
关键字,不加默认是and
,最终的sql语句为:
SELECT id,name,password,age,tel FROM user WHERE (age < ? OR age > ?)
也是顺利的查了出来
四.null判定
以TB为例,我们购物时进行条件筛选时,可以选择单条件,也可以选择多条件,如上,我的条件就变成price>3000,price<null,这种情况按照以上介绍的查询的方式就会出现问题,如图:
显然,这种情况在开发过程中时不被允许的。所以要求我们针对null的情况要解决如下问题:
用户在输入值的时候:
1.如果只输入第一个框,说明要查询大于该价格的商品
2.如果只输入第二个框,说明要查询小于该价格的商品
3.如果两个框都输入了,说明要查询价格在两个范围之间的商品
于是,我们可以
新建一个模型类,让其继承Brand类,并在其中添加price2属性,Brand02 在拥有Brand属性后同时添加了price2属性
@Data
public class Brand
private Long id;
private String name;
private Double price;
@Data
public class Brand02 extends Brand
private Integer price2;
解决了实体的问题,再来解决条件的问题
@SpringBootTest
class Mybatisplus02
@Autowired
private BrandDao brandDao;
@Test
void testGetAll()
BrandQuery bq = new BrandQuery();
LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<Brand>();
lqw.lt(null!=bq.getPrice2(),User::getPrice, bq.getPrice2());
lqw.gt(null!=bq.getPrice(),User::getPrice, bq.getPrice());
List<Brand> brands = brandDao.selectList(lqw);
System.out.println(brands);
解读:
如果两个属性不为空,则查询price,price2区间范围内
如果有一个属性为空,则查询不为空的区间
实现的核心在于lt()、gt()方法,condition为boolean类型上述的null!=bq.getPrice2()
与之对应,返回true,则添加条件,返回false则不添加条件,条件的生效与否就是靠的这个设计!
最后,也是在null的条件下完成了查询:
spring data jpa 的分页以及条件查询
spring data jpa的分页以及条件查询:
1.分页是主要
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
2.条件查询主要是:
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
直接写一个例子:
NetWorkInfo netWorkInfo = new NetWorkInfo(); netWorkInfo.setWdName(query); netWorkInfo.setWdCode(query); PageRequest pageable = PageRequest.of(page - 1, size, Sort.Direction.DESC, "id"); //分页信息 //查询条件组装 Specification<NetWorkInfo> spec = new Specification<NetWorkInfo>() { @Override public Predicate toPredicate(Root<NetWorkInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Path<String> name = root.get("wdName"); Predicate p1 = cb.like(name, "%" + netWorkInfo.getWdName() + "%"); Path<String> code = root.get("wdCode"); Predicate p2 = cb.like(code, "%" + netWorkInfo.getWdCode() + "%"); List<Predicate> listAnd=new ArrayList<>(); //组装and语句 listAnd.add(p1); listAnd.add(p2); Predicate predicateAnd = cb.and(listAnd.toArray(new Predicate[listAnd.size()])); //AND查询加入查询条件 return query.where(predicateOr).getRestriction(); } }; Page<NetWorkInfo> pageList = netWorkInfoDao.findAll(spec, pageable);
另外一种可以这样写:
NetWorkInfo netWorkInfo = new NetWorkInfo(); netWorkInfo.setWdName(query); netWorkInfo.setWdCode(query); PageRequest pageable = PageRequest.of(page - 1, size, Sort.Direction.DESC, "id"); //分页信息 //查询条件组装 Specification<NetWorkInfo> spec = new Specification<NetWorkInfo>() { @Override public Predicate toPredicate(Root<NetWorkInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Path<String> name = root.get("wdName"); Predicate p1 = cb.like(name, "%" + netWorkInfo.getWdName() + "%"); Path<String> code = root.get("wdCode"); Predicate p2 = cb.like(code, "%" + netWorkInfo.getWdCode() + "%"); return cb.and(p1,p2); } }; Page<NetWorkInfo> pageList = netWorkInfoDao.findAll(spec, pageable);
dao层数据实现:
package com.example.react.dao; import com.example.react.model.NetWorkInfo; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface NetWorkInfoDao extends JpaRepository<NetWorkInfo,Long> { @Query(value = "select * from network_info where wd_name like %?1% order by id desc ", nativeQuery = true) List<NetWorkInfo> getModelByLikeQuery(String query); @Query(value = "select * from network_info where wd_name = ?1", nativeQuery = true) List<NetWorkInfo> getModelByName(String name); @Query(value = "select * from network_info where wd_name = ?1 and id !=?2", nativeQuery = true) List<NetWorkInfo> getModelByNameAndNotId(String name,long id); @Query(value = "select * from network_info where id = ?1", nativeQuery = true) List<NetWorkInfo> getModelById(Integer id); @Query(value = "select * from network_info where id = ?1", nativeQuery = true) NetWorkInfo getModelId(Integer id); @Query(value = "select * from network_info order by id ", nativeQuery = true) List<NetWorkInfo> getModelList(); Page<NetWorkInfo> findAll(Specification<NetWorkInfo> spec, Pageable pageable); }
注意:只是写了关键的数据
以上是关于MybatisPlusMP的分页查询多条件查询以及查询过程中解决null的空值判定的主要内容,如果未能解决你的问题,请参考以下文章
掌握MyBatisPlus中的分页及条件查询构建 | 黑马程序员