SpringDataJpa(四) Specification 动态查询

SpringDataJpa(四) Specification 动态查询

1)JpaSpecificationExecutor 方法列表:
public interface JpaSpecificationExecutor<T> {
    T findOne(Specification<T> var1);
    List<T> findAll(Specification<T> var1);
    Page<T> findAll(Specification<T> var1, Pageable var2);
    List<T> findAll(Specification<T> var1, Sort var2);
    long count(Specification<T> var1);
}
  • T findOne(Specification var1); 查看单个对象
  • List findAll(Specification var1); 查询记录列表
  • Page findAll(Specification var1, Pageable var2); 分页查询
    - Page: 是springData 封装的pageBean对象,里面包含分页基本属性
    - Pageable: 分页条件,接口,构造函数要传入两个参数(当前查询页数,每页记录数)
    eg: Pageable pageable = new PageRequest(0, 2);
  • List findAll(Specification var1, Sort var2); 排序查询
  • long count(Specification var1); 统计查询
2)自定义查询:
  public interface Specification<T> {
     Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder    var3);
}
  • 实现Specification接口
  • 实现toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) 方法
    - root: 查询根对象
    - CriteriaQuery: 顶层查询对象,自定义查询方式(了解:一般不用)
    - CriteriaBuilder: 查询构造器,封装了基本查询功能

测试:

1.实体类 Customer
/**
 *  客户实体类
 */
@Entity
@Table(name = "t_cst_customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cust_id")
    private Long custId;
    @Column(name = "cust_name")
    private String custName;
    @Column(name = "cust_industry")
    private String custIndustry;
    @Column(name = "cust_source")
    private String custSource;
    @Column(name = "cust_level")
    private String custLevel;
    @Column(name = "cust_address")
    private String custAddress;
    @Column(name = "cust_phone")
    private String custPhone;
 }
2.dao层 CustomerDao
  public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {
}

3.测试类
1) 单条件精准查询
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:applicationContext.xml")
public class SpecTest {

    @Autowired
    private CustomerDao customerDao;


    /**
     *  单条件查询
     */
    @Test
    public void test_findOne(){
        /**
         * 匿名内部类
         *  自定义查询:
         *     1.实现Specification 接口(提供泛型,要查询的实体类的类型)
         *     2.实现predicate方法(构造查询条件)
         *      root: 查询的根对象,要查询的任何属性从根对象中获取
         *                (这个根对象可代表要查询的实体对象)
         *          criteriaBuilder:查询构造器内部封装了很多查询方法
         *              eg:equal(path属性, "值")   精准查询
         */
        Specification<Customer> specification = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Object> custName = root.get("custName");
                // jqpl:from Customer where custName = ?
                Predicate predicate = criteriaBuilder.equal(custName, "张三");
                return predicate;
            }
        };
        Customer customer = customerDao.findOne(specification);
        System.out.println(customer);
    }
}
2)多条件精准查询

拼接条件 and | or

 /**
     *  多条件查询
     *     多条件拼接
     */
    @Test
    public void test_manyCriteria(){

        Specification<Customer> specification = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取属性
                Path<Object> custName = root.get("custName");
                Path<Object> custIndustry = root.get("custIndustry");

                //2.构造查询条件
                Predicate p1 = criteriaBuilder.equal(custName, "张三");
                Predicate p2 = criteriaBuilder.equal(custIndustry, "it教育");

                //3.拼接条件 and | or
                Predicate predicate = criteriaBuilder.and(p1, p2);
                return predicate;
            }
        };

        Customer customer = customerDao.findOne(specification);
        System.out.println(customer);
    }

3)模糊查询

对于 like, gt, ge, lt, le 等查询方式,不能直接传入 path对象,需要说明比较的类型(String, Integer… ) path.as(.class)

    /**
     *  模糊查询
     */
    @Test
    public void test_like(){
        /**
         * 对于 like, gt, ge, lt, le 等查询方式,不能直接传入 path对象
         *     还要说明比较的类型(String, Integer... ) path.as(.class)
         */
        Specification<Customer> specification = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //获取要查询的属性
                Path<Object> custName = root.get("custName");
                //构造查询条件
                Predicate predicate = criteriaBuilder.like(custName.as(String.class), "%三%");
                return predicate;
            }
        };

        List<Customer> list = customerDao.findAll(specification);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
4)对排序结果排序

Sort.Direction.DESC 倒序
Sort.Direction.ASC 正序

    /**
     * 对于 like, gt, ge, lt, le 等查询方式,不能直接传入 path对象
     *     还要说明比较的类型(String, Integer... ) path.as(.class)
     */
    @Test
    public void test_sort(){
        Specification<Customer> specification = null;
        /**
         *  创建排序对象:
         *       需要传递参数(排序方式, 排序的属性)
         *          Sort.Direction.DESC  倒序
         *          Sort.Direction.ASC   正序
         */
        Sort sort = new Sort(Sort.Direction.DESC, "custId");
        List<Customer> list = customerDao.findAll(specification, sort);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
5)分页查询
    /**
     * 分页查询
     * Page<T> findAll(Specification spec, Pageable pageable); 带有条件分页
     * Page<T> findAll(Pageable pageable);  不带条件分页
     *     Page : springData 封装好的pageBean 对象,包含分页的基本属性
     *     Pageable: 分页条件,接口,构造函数要传入两个参数(当前查询页数,每页记录数)
     *
     */
    @Test
    public void test_page(){

        Specification specification = null;
        //创建 分页条件对象
        Pageable pageable = new PageRequest(0, 2);
        Page page = customerDao.findAll(specification, pageable);

        //获取记录集合Test
        List list = page.getContent();
        for (Object o : list) {
            System.out.println(o);
        }
        System.out.println(page.getTotalElements()); //获取总记录数
        System.out.println(page.getTotalPages());  //获取总页数
    }
}
  
发布了47 篇原创文章 · 获赞 7 · 访问量 2332

猜你喜欢

转载自blog.csdn.net/qq_43616898/article/details/104407523
今日推荐