Spring Data Jpa - 动态查询

如何使用Spring Data Jpa帮助我们实现一些复杂的查询呢?

1. 接口分析

  • 我们需要将我们自定义的接口继承一个叫做JpaSpecificationExecutor的接口,查看这个接口的源码你会发现,每个方法都有一个Specification类型的参数,其实这个参数就是我们可以进行复杂查询的关键。
public interface JpaSpecificationExecutor<T> {

	T findOne(Specification<T> spec);

	List<T> findAll(Specification<T> spec);

	Page<T> findAll(Specification<T> spec, Pageable pageable);

	List<T> findAll(Specification<T> spec, Sort sort);

	long count(Specification<T> spec);
}
  • 点进Specification,这也是一个接口,其中只有一个toPredicate方法,这个方法里面我们就可以自定义查询方式,三个参数的用法如下:

Root root:查询的根对象,可以从中获取查询的属性

CriteriaQuery<?> query:顶层查询对象,自定义查询的方式

CriteriaBuilder cb:查询的构造器,封装了很多查询条件

public interface Specification<T> {
	Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}

2.具体实现方式

场景一:查询以“张”开头的用户信息,并以id降序排序

@Test
public void testSpec1(){
    Specification<User> spec = new Specification<User>() {
        @Override
        public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            //获取userName属性
            Path<Object> userName = root.get("userName");
            //传入获取的属性并指定类型
            Predicate like = cb.like(userName.as(String.class), "张%");
            return like;
        }
    };
    List<User> users = userDao.findAll(spec);
    System.out.println(users);
}

场景二:查询所在地为北京的用户,并分页显示

@Test
public void testSpec2(){
    Specification<User> spec = new Specification<User>() {
        @Override
        public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            Path<Object> userAddress = root.get("userAddress");
            //equal方法不需要传入参数类型
            Predicate predicate = cb.equal(userAddress, "北京");
            return predicate;
        }
    };
    //创建一个分页对象
    // 第一个参数代表第几页 
    // 第二个参数代表每页显示几条数据
    Pageable pageable = new PageRequest(1, 2);
    Page<User> page = userDao.findAll(spec, pageable);
    System.out.println("当前页:"+page.getNumber());
    System.out.println("当前页记录条数:"+page.getNumberOfElements());
    System.out.println("总记录条数:"+page.getTotalElements());
    System.out.println("总页数:"+page.getTotalPages());
    System.out.println("当前页数据数据:"+page.getContent());
}

3.其他方法对应的sql含义

  • 上面两个案例介绍了equal和like的使用,其他方法使用方式和这两个是一样的,大家可以根据上面的使用来测试
方法名称Sql对应关系
equalfiled = value
gt(greaterThan )filed > value
lt(lessThan )filed < value
ge(greaterThanOrEqualTo )filed >= value
le( lessThanOrEqualTo)filed <= value
notEqulefiled != value
likefiled like value
notLikefiled not like value
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值