Jpa,关于JpaSpecificationExecutor<>的动态查询

【1】配置和JAR包和之前的jpa单表查询一样,这里就不导入代码了

【2】有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。

         这里我们要是用到Test单元测试,记得把这两个注解加到类前,不然不能使用Spring的配置

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpecTest {

【3】动态查询步骤

         1.利用IOC导入我们要用的dao层接口

         2.new出一个Specification接口,需要填写我们对哪个实体类进行操作

         3.这个接口会自带一个Predicate类的方法,里面有三个参数,Root,CriteriaQuery,CriteriaBuilder,

                Root,比较属性名称

                CriteriaBuilder,查询方式

                CriteriaQuery,代表一个顶层查询对象,用来自定义查询(大部分情况下不用)

        4.用root.get(我们实现类中的属性)获得我们的属性参数

        5.在用CriteriaBuilder.euqal(path,value),这里的equal不是我们String中的equal。得到predicate对象。

        6.return predicate

        7.调用我们接口的方法,因为接口继承了JpaRepository<,>和JpaSpecificationExecutor<r>

           这两个接口里面都有findone方法,就是查询一个数据。JpaRepository中的findone(主键值)的参数填写的是主键,也就是根据主键查询,而JpaSpecificationExcutor中的finddone,里面填写的是Specification。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpecTest {
    /*Spec动态查询*/
    @Autowired
    private CustmoerDao custmoerDao;
    @Test
    public void testSpec() {
        Specification<Customer> spec = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //获取比较的属性
                Path<Object> custName = root.get("custName");
                //构造查询条件  select * from cst_custmoer where cust_name="kfc"
                Predicate predicate = criteriaBuilder.equal(custName, "kfc");
                return predicate;
            }
        };
        Customer cus = custmoerDao.findOne(spec);
        System.out.println(cus);

【2】利用动态进行联合查询

        原理都一样,直接上代码,CriteriaBuilder中还有一个and方法,目的是把两个predicate结合到一起查询

 @Test
    public void testSpec2() {
        Specification<Customer> spec = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Object> custName = root.get("custName");
                Path<Object> custIndustry = root.get("custIndustry");
                Predicate predicate = criteriaBuilder.equal(custName, "kfc");
                Predicate predicate1 = criteriaBuilder.equal(custIndustry, "中国石油大学周边");
                Predicate and = criteriaBuilder.and(predicate, predicate1);
                return and;
            }
        };
        Customer one = custmoerDao.findOne(spec);
        System.out.println(one);

【3】spec的模糊查询

         这里需要说一下,equals方法是可以直接通过path对象进行比较的

         而其他的方法,例如like,gt,ge,lt,需要根据path指定的数据类型,进行比较

         gt:greaterThan ,比我们传入的value大的数据

         lt:lessthan,比我们传入的value小的数据

         ge:相当于大于等于

         le:相当于小于等于

         notEqual:不等于

         like:模糊查询

         notLike:查询的结果和like相反

         比较的类型:path.as(数据类型.class)

        这里如果查询出多个数据,那么就可以用Sort排序


    @Test
    public void  testLikeFind(){
        Specification<Customer> spec=new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Object> custName = root.get("custName");
                Predicate like = criteriaBuilder.like(custName.as(String.class), "K%");
                return like;
            }
        };
//        List<Customer> all = custmoerDao.findAll(spec);
//        for (Customer customer : all) {
//            System.out.println(customer);
//        }
        //排序查询
        //需要写一个sort排序,第一个写规则,第二个参数写根据哪个属性排序
        Sort sort=new Sort(Sort.Direction.DESC,"custId");
        List<Customer> all = custmoerDao.findAll(spec, sort);
        for (Customer customer : all) {
            System.out.println(customer);
        }
    }

【4】分页查询

        利用到Pageable,这个大家应该很熟悉了。第一个参数传查询页数,第二个参数传查询的数目。

/*分页查询,Pageable*/
    @Test
    public void testSpec4(){

        Pageable pageable=new PageRequest(0,2);//参数1:当前查询页数,第二个每页查询数量
        Page<Customer> all = custmoerDao.findAll(pageable);
        System.out.println(all.getTotalElements());//查询总数据数
        List<Customer> content = all.getContent();//获取数据
        for (Customer customer : content) {
            System.out.println(customer);
        }
        System.out.println(all.getTotalPages());//得到总页数
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hpeacheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值