1. Example
特点:Example查询是一种基于实体类实例的查询方式。通过创建一个实体类的实例并设置其属性值,可以动态构建查询条件。这种方式无需编写复杂的查询语句,适合于查询条件不固定或需要根据用户输入动态构建查询的场景。
适用场景:当需要基于实体类的某个或多个属性进行模糊匹配或精确匹配时,可以使用Example查询。
private void queryByExample(){
// 使用Example查询
logger.info("使用Example查询");
User user = new User();
user.setUserName("azu");
Example<User> example = Example.of(user);
List<User> userList = userRepository.findAll(example);
for (User user1 : userList) {
logger.info(user1.toString());
}
}
2. Specification
特点:Specification查询提供了更加灵活和强大的查询构建能力。它允许使用Lambda表达式和JPA Criteria API来构建复杂的查询条件,可以方便地实现各种逻辑运算和条件组合。
适用场景:当需要构建复杂的查询条件,如多条件组合、子查询、分组聚合等时,Specification查询是一个很好的选择。它特别适合于构建动态查询,能够根据运行时条件动态构建和执行查询。
private void queryBySpecification() {
// 使用Specification查询
logger.info("使用Specification查询");
Specification<User> userSpecification = new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
predicates.add(criteriaBuilder.equal(root.get("userName"),"azu"));
predicates.add(criteriaBuilder.like(root.get("email"),"azu%"));
// 将一个 Predicate 列表(predicates)中的所有条件组合成一个单一的 Predicate,并使用逻辑与(AND)操作来连接这些条件
Predicate and = criteriaBuilder.and(predicates.toArray(new Predicate[0]));
return and;
}
};
List<User> userList = userRepository.findAll(userSpecification);
for (User user : userList) {
logger.info(user.toString());
}
}
2. Criteria
特点:Criteria查询是JPA中提供的一种类型安全的查询方式。它使用CriteriaBuilder和CriteriaQuery来构建查询,可以方便地构建各种查询条件、排序、分组和聚合操作。Criteria查询是JPA中较为底层和强大的查询方式。
适用场景:当需要构建类型安全的查询,或者需要利用JPA提供的完整查询功能时,可以使用Criteria查询。它适用于构建复杂且需要精确控制查询细节的场景。
private void queryByCriteria() {
// 使用Criteria查询
logger.info("使用Criteria查询");
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);
query.select(root);
query.where(cb.equal(root.get("userName"),"azu"));
List<User> userList = entityManager.createQuery(query).getResultList();
for (User user : userList) {
logger.info(user.toString());
}
}
查询结果展示
2024-03-14 20:57:51.906 INFO 18324 --- [ main] c.neo.repository.JpaSpecificationTests : 使用Example查询
Hibernate: select user0_.id as id1_1_, user0_.email as email2_1_, user0_.nick_name as nick_nam3_1_, user0_.pass_word as pass_wor4_1_, user0_.reg_time as reg_time5_1_, user0_.user_name as user_nam6_1_ from user user0_ where user0_.user_name=?
2024-03-14 20:57:51.985 INFO 18324 --- [ main] c.neo.repository.JpaSpecificationTests : User{id=1, userName='azu', passWord='azu123456', email='azu@qq.com', nickName='阿祖', regTime='2024-03-14'}
2024-03-14 20:57:51.985 INFO 18324 --- [ main] c.neo.repository.JpaSpecificationTests : 使用Specification查询
Hibernate: select user0_.id as id1_1_, user0_.email as email2_1_, user0_.nick_name as nick_nam3_1_, user0_.pass_word as pass_wor4_1_, user0_.reg_time as reg_time5_1_, user0_.user_name as user_nam6_1_ from user user0_ where user0_.user_name=? and (user0_.email like ?)
2024-03-14 20:57:51.991 INFO 18324 --- [ main] c.neo.repository.JpaSpecificationTests : User{id=1, userName='azu', passWord='azu123456', email='azu@qq.com', nickName='阿祖', regTime='2024-03-14'}
2024-03-14 20:57:51.991 INFO 18324 --- [ main] c.neo.repository.JpaSpecificationTests : 使用Criteria查询
Hibernate: select user0_.id as id1_1_, user0_.email as email2_1_, user0_.nick_name as nick_nam3_1_, user0_.pass_word as pass_wor4_1_, user0_.reg_time as reg_time5_1_, user0_.user_name as user_nam6_1_ from user user0_ where user0_.user_name=?
2024-03-14 20:57:52.007 INFO 18324 --- [ main] c.neo.repository.JpaSpecificationTests : User{id=1, userName='azu', passWord='azu123456', email='azu@qq.com', nickName='阿祖', regTime='2024-03-14'}