Dao接口
public interface CustomerDao extends JpaRepository<Customer,Long>,JpaSpecificationExecutor<Customer> {
}
测试方法:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpecTest {
@Autowired
private CustomerDao customerDao;
/**
* 自定义查询条件
* 1.实现Specification接口(提供泛型:查询的对象类型)
* 2.实现toPredicate方法(构造查询条件)
* 3.需要借助方法参数中的两个参数(
* root:获取需要查询的对象属性
* CriteriaBuilder:构造查询条件的,内部封装了很多的查询条件(模糊匹配,精准匹配)
* )
* predicate: 谓语;述语 criteria(criterion) 标准;准则;规范;准据
* 案例:根据客户名称查询,查询客户名为百度的客户
* 查询条件
* 1.查询方式:cb对象
* 2.比较的属性名称:root对象
*/
@Test
public void testSpec() {
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//1.获取比较的属性
Path<Object> custName = root.get("custName");
//2.构造查询条件:select * from cst_customer where cust_name = '百度'
/**
* 第一个参数:需要比较的属性(path对象)
* 第二个参数:当前需要比较的取值
*/
Predicate predicate = cb.equal(custName, "百度");//进行精准的匹配(比较的属性,比较的属性的取值)
return predicate;
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
/**
* 多条件查询
* 案例:根据客户名(新东方)和客户所属行业查询(教育)
* root: 获取属性,客户名,所属行业
* cb: 构造查询
* 1.构造客户名的精准匹配查询
* 2.构造所属行业的精准匹配查询
* 3.将以上两个查询联系起来
*/
@Test
public void testSpec1() {
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 p1 = cb.equal(custName, "新东方");
//2、构造所属行业的精准匹配查询
Predicate p2 = cb.equal(custIndustry, "教育");
//3、将多个查询条件组合到一起:组合(满足条件一并且满足条件二:与关系,满足条件一或满足条件二即可:或关系)
Predicate predicate = cb.and(p1, p2);//以与的形式拼接多个查询条件
// cb.or();//以或的形式拼接多个查询条件
return predicate;
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
/**
* 完成根据客户名称的模糊查询,返回客户列表
*
* equal: 直接的到path对象(属性),然后进行比较即可
* gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较
* 指定参数类型:path.as(类型的字节码对象)
*
* 添加排序: 创建排序对象,需要调用带参数的构造方法实例化sort对象
* 第一个参数:排序的顺序(倒序,正序)
* Sort.Direction.DESC:倒序
* Sort.Direction.ASC: 升序
* 第二个参数:排序的属性名称
*/
@Test
public void testSpec3() {
// 构造查询条件参数
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//查询属性:客户名
Path<Object> custName = root.get("custName");
//查询方式:模糊匹配
Predicate predicate = cb.like(custName.as(String.class), "%美%");
return predicate;
}
};
// 排序参数
Sort sort = new Sort(Sort.Direction.DESC,"custId");
// 按照条件查询,并且添加排序参数
List<Customer> list2 = customerDao.findAll(spec, sort);
for (Customer customer : list2) {
System.out.println(customer);
}
}
/**
* 分页查询:
* Specification: 查询条件
* Pageable: 分页参数
* 分页参数: 查询的页码,每页查询的条数
* findAll(Specification,Pageable): 带有条件的分页
* findAll(Pageable): 没有条件的分页
* 返回:Page(springDataJpa为我们封装好的pageBean对象,数据列表,共条数)
* PageRequest对象是Pageable接口的实现类
* 创建PageRequest的过程中,需要调用他的构造方法传入两个参数
* 第一个参数:当前查询的页数(从0开始)
* 第二个参数:每页查询的数量
*/
@Test
public void testSpec4() {
// 分页查询参数
Pageable pageable = new PageRequest(0,2);
// 分页查询
Page<Customer> page = customerDao.findAll(null, pageable);
System.out.println(page.getContent()); //得到每页数据集合列表
System.out.println(page.getTotalElements());//得到总条数
System.out.println(page.getTotalPages());//得到总页数
}
}
[Customer{custId=2, custAddress='null', custIndustry='互联网', custLevel='null', custName='百度', custPhone='null', custSource='null'},
Customer{custId=3, custAddress='null', custIndustry='互联网', custLevel='null', custName='阿里巴巴', custPhone='null', custSource='null'}]
12
6