欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring DataJPA的Specifications动态查询

程序员文章站 2022-04-25 19:33:11
...

Spring DataJPA的Specifications动态查询

JpaSpecificationExecutor接口的方法
T findOne(Specification<T> var1);  //查询单个对象

List<T> findAll(Specification<T> var1);  //查询列表
//查询全部 分页  Pageable:分页参数
//返回值:分页PageBean(springdatajpa提供的)
Page<T> findAll(Specification<T> var1, Pageable var2);
//查询列表,
//Sort:排序参数
List<T> findAll(Specification<T> var1, Sort var2);
//统计查询
long count(Specification<T> var1);
Specification对象:查询条件(进行查询时,需要自定义我们自己的Specification实现类)

​ 实现的方法:

/*
* Root:代表查询的跟对象(查询的任何属性都可以从跟对象中获取)
* CriteriaQuery:顶层查询对象,自定义查询方式(了解)
* CriteriaBuilder:查询的构造器,封装了很多查询条件
*/
Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);//封装查询条件
dao层接口
public interface CustomerDao extends JpaRepository<Customer,Integer>, JpaSpecificationExecutor<Customer> {

}
根据客户名查询客户
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpecTest {

    @Resource
    CustomerDao customerDao;

    /*
     * 根据条件,查询单个对象
     * */
    @Test
    public void testSpec(){
        //匿名内部类
        /*
        * 定义一查询条件,
        *   1.实现Specification接口(提供泛型,就是查询的对象类型)
        *   2.实现toPredicate方法(构造查询条件)
        *   3.需要借助方法参数中的两个参数(root:获取需要查询的对象属性;CriteriaBuilder:构造查询条件的,内部封装了很多查询条件(模糊匹配,精准匹配))
        *
        * 案例:根据客户名查询
        *   查询条件:
        *       1.查询方式,在CriteriaBuilder对象中
        *       2.比较的属性名称:在Root对象中
        * */
        Specification<Customer> spec = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                //获取比较的属性
                Path<Object> name = root.get("name");
                //构造查询条件,select * from customer where name = "heima"
                //参数1:需要比较的属性Path对象 参数2;当前需要比较的取值
                Predicate predicate = cb.equal(name, "heima");//进行精准匹配,比较属性的取值
                return predicate;
            }
        };
        Customer customer = customerDao.findOne(spec);
        System.out.println(customer);
    }
}
多个条件进行查询(接口内容不需要写)
/*
* 多条件查询:根据客户名和客户所属行业进行查询
*  */
@Test
public void testSepc2(){
/*
* root:获取属性:客户名称,所属行业
* cb:构造查询
*   1.构造客户名的精准匹配查询
*   2.构造所属行业的精准匹配查询
*   3.将以上两个查询联系起来
* */
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//获取客户名称,所属行业
Path<Object> name = root.get("name");
Path<Object> industry = root.get("industry");
//.构造客户名的精准匹配查询
Predicate predicate1 = cb.equal(name, "heima");
Predicate predicate2 = cb.equal(industry, "教育");
//将以上两个查询联系起来(组合:满足条件1并且满足条件2,满足条件1或者满足条件2)
Predicate predicate = cb.and(predicate1, predicate2);  //以与的形式拼接条件
//cb.or()  以或的方式拼接条件
return predicate;
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
根据用户名进行模糊查询
/*
    * 案例:根据客户名进行迷糊查询
    * equal:直接得到path对象(属性),然后进行比较即可
    * gt lt le like:得到path对象,根据path指定比较的参数类型,再去进行比较 path.as(参数类型的字节码)
    * */
@Test
public void testSpec3(){
    Specification<Customer> spec = new Specification<Customer>() {
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
            Path<Object> name = root.get("name");
            Predicate predicate = cb.like(name.as(String.class), "%马%");
            return predicate;
        }
    };
    List<Customer> customerList = customerDao.findAll(spec);
    System.out.println(customerList);
}
根据客户名进行迷糊查询并按照id排序
/*
     * 案例:根据客户名进行模糊查询并按照id排序
     * */
@Test
public void testSpec4(){
    Specification<Customer> spec = new Specification<Customer>() {
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
            Path<Object> name = root.get("name");
            Predicate predicate = cb.like(name.as(String.class), "%马%");
            return predicate;
        }
    };
    //创建排序对象,需要调用构造方法实例化对象
    //参数1:排序的顺序(Sort.Direction.DESC:倒序 Sort.Direction.ASC:升序);参数2:排序的属性名
    Sort sort = new Sort(Sort.Direction.DESC,"id");
    List<Customer> customerList = customerDao.findAll(spec,sort);
    System.out.println(customerList);
}
分页查询
/*
* 分页查询
* findAll(Specification,Pageable):带有条件的分页
* findAll(Pageable):没有条件的分页
*   参数1:Specification
*   参数2:Pageable
*       查询的页码,每页查询的条数
*
* 返回:Page对象:SpringDataJpa为我们封装好的pageBean对象
* */
@Test
public void testSpec5(){
/*
* PageRequest树Pageable接口的实现类
* 创建PageRequest时需要调用构造方法传入两个参数
*   参数1:当前查询的页数(从0开始)
*   参数2:当前查询的总数
* */
Pageable pageable = new PageRequest(0,3);
//分页查询
Page<Customer> page = customerDao.findAll(pageable);
System.out.println(page.getTotalElements());  //表中的总条数
System.out.println(page.getTotalPages());   //得到总页数
System.out.println(page.getContent());   //得到结果列表,list集合
}
相关标签: SpringDataJPA