在查询某个实体时,给定的条件不固定,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象
抽象方法有JpaSpecificationExecutor提供
方法都需要传入一个Specification对象,该对象也是借口
里面只有一个方法,可以通过匿名内部类的实现方式实现
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
public class SpecTest {
@Autowired
private UsersDao usersDao;
@Test
public void testSpec(){
/**
* 匿名内部类
*
* 自定义查询条件
* 1、实现Specification接口(提供返现,查询的对象类型)
* 2、实现toPredicate方法(构造查询条件)
* 3、需要借助方法参数中的两个参数
* root:获取需要查询的对象属性
* CriteriaBuilder: 构造查询条件的,内部封装了很多的查询条件(模糊匹配,精准匹配)
*
* 根据用户名查询
*/
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//获取比较的属性
Path<Object> userName = root.get("userName");
//构造查询条件
Predicate predicate = criteriaBuilder.equal(userName, "小黑 ");
return predicate;
}
};
Users users = usersDao.findOne(spec);
System.out.println(users);
}
/**
* 多条件查询
* 案例:根据用户名和用户id进行查询
*/
@Test
public void testSpec1(){
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<Object> userName = root.get("userName");
Path<Object> userId = root.get("userId");
Predicate p1 = criteriaBuilder.equal(userName, "小黑");
Predicate p2 = criteriaBuilder.equal(userId, 1);
Predicate result = criteriaBuilder.and(p1, p2);
return result;
}
};
Users user = usersDao.findOne(spec);
System.out.println(user);
}
/**
* 根据用户名称的模糊匹配,返回客户列表
* equal 方法直接得到path对象(属性),然后进行比较即可
* gt,lt,ge,le,like 方法得到Path独享,根据path指定比较的参数类型,再去进行比较
* 指定参数类型,path.as(类型的字节码对象)
*/
@Test
public void testSpec3(){
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<Object> userName = root.get("userName");
Predicate like = criteriaBuilder.like(userName.as(String.class), "%小%");
return like;
}
};
// List<Users> all = usersDao.findAll(spec);
// for (Users user: all
// ) {
// System.out.println(user);
// }
/**添加排序
* 创建排序对象
* 第一个参数:排序的顺序
* 第二个参数:排序的属性名称
*/
Sort sort = new Sort(Sort.Direction.DESC, "userId");
List<Users> all = usersDao.findAll(spec, sort);
for (Users user: all
) {
System.out.println(user);
}
}
/**
* 分页查询
*/
@Test
public void testSpec4(){
Specification spec = null;
/**
* 创建PageRequest的工程中,需要调用他的构造方法传入两个参数
* 第一个参数: 当前查询的页数(从0开始)
* 第二个参数: 每页查询的数量
*/
Pageable pageable = new PageRequest(0,2);
//分页查询
Page<Users> page = usersDao.findAll(null, pageable);
//得到数据集合列表
System.out.println(page.getContent());
//得到总条数
System.out.println(page.getTotalElements());
//得到总页数
System.out.println(page.getTotalPages());
}
}