Specifications动态查询:
首先 需要在dao层实现JpaRepository ,JpaSpecificationExecutor接口
CustomerDao (客户)
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {}
接着在测试类中进行测试:
测试一:根据单一条件,查询单个对象
@Autowired
private CustomerDao customerDao;
@Test
public void testSpec()
{
//步骤一:实现匿名内部类
//步骤二:实现toPredicate方法(构造查询条件)
Specification<Customer> spec=new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder CriteriaBuilder) {
//1.获取比较的属性名称
Path<Object> custName = root.get("custName");
//2.构造查询条件 : select * from cst_customer where cust_name="迅腾软件"
/*
第一个参数:需要比较的属性(path对象)
第二个参数:当前需要比较的取值
*/
Predicate predicate = CriteriaBuilder.equal(custName, "迅腾软件");//进行精准的匹配(先比较属性名,再比较的该属性的取值)
return predicate;
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
测试二:根据多条件 查询客户名(迅腾软件公司) 和客户所属行业查询(xt教育)单个对象
@Test
public void testSpec1()
{
//步骤一:实现匿名内部类
//步骤二:实现toPredicate方法(构造查询条件)
Specification<Customer> spec=new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Path<Object> custName = root.get("custName");
Path<Object> custIndustry = root.get("custIndustry");
//构造查询
//1.构造客户名的精准匹配查询
Predicate predicate = cb.equal(custName, "迅腾软件");
//2.构造所属行业的精准匹配查询
Predicate predicate1 = cb.equal(custIndustry, "xt教育");
//3. 将多个查询条件组合到一起:组合(满足条件一并且满足条件二:与关系,满足条件一或满足条件二即可:或关系)
Predicate and = cb.and(predicate,predicate1);//以与的形式拼接多个查询条件
//cb.or(predicate,predicate1);//以或的形式拼接多个查询条件
return and;
}
};
//如果数据只有一个就用findOne来做
Customer customer = customerDao.findOne(spec);
/*
如果数据只有多个就用findAll来做
customerDao.findAll();
*/
System.out.println(customer);
}
测试三:完成根据客户名称的模糊匹配 ,客户名称以‘ 迅腾软件’ 开头
@Test
public void testSpec3()
{
//步骤一:实现匿名内部类
//步骤二:实现toPredicate方法(构造查询条件)
//步骤三:在findAll方法中新增一个排序参数sort
Specification<Customer> spec=new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//查询属性:客户名
Path<Object> custName = root.get("custName");
//查询方式模糊匹配
Predicate like = cb.like(custName.as(String.class), "迅腾软件%");
return like;
}
};
//添加排序
//创建排序对象,需要调用构造方法实例化sort对象
//第一个参数,排序的顺序(倒叙,正序)
// Sort.Direction.DESC;倒叙
// Sort.Direction.ASC : 升序
//第二个参数,排序的属性名称
Sort sort=new Sort(Sort.Direction.DESC,"custId");
List<Customer> list = customerDao.findAll(spec, sort);
for (Customer customer : list) {
System.out.println(customer);
}
}
测试四:分页查询
* 分页查询
* Spectification:查询条件
* Pageable:分页参数
* 分页参数:查询的页码,每页查询的条数
* findAll(Specification,Pageable):带有条件的分页
* findAll(Pageable):没有条件的分页
*
* 返回:Page(Spring DataJpa为我们封装好的pageBean对象,数据列表,共条数)
@Test
public void testSpec4()
{
//PageRequest对象是Pageable接口的实现类
/*
*
* 创建PageRequest的过程中,需要调用她的构造方法传入两个参数
* 第一个参数:当前查询的页数(从0开始)
* 第二个参数:每页查询的数量
*
* */
Specification spec=null;
Pageable pageable=new PageRequest(0,2);
Page<Customer> page = customerDao.findAll(null, pageable);
System.out.println(page.getTotalElements());//得到总条数
System.out.println(page.getTotalPages());//得到总页数
System.out.println(page.getContent());//得到数据集合列表
}