学习进度条
每日总结(SpringBoot 条件查询专题)
今日学习时间:1小时
今日代码量:100行
今日博客:1篇(SpringBoot JPA 条件查询的5种实现方式)
1. JPA 方法命名查询(无需SQL)
// 1. 按名称精确查询
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByUsername(String username);
// 2. 多条件AND查询
List<User> findByUsernameAndAgeGreaterThan(String username, int age);
// 3. 模糊查询 + 排序
List<User> findByUsernameContainingOrderByCreateTimeDesc(String keyword);
}
2. @Query 注解(JPQL)
// 4. JPQL条件查询
@Query("SELECT u FROM User u WHERE u.age BETWEEN :min AND :max")
List<User> findUsersByAgeRange(@Param("min") int minAge,
@Param("max") int maxAge);
// 5. 原生SQL查询
@Query(value = "SELECT * FROM users WHERE status = :status", nativeQuery = true)
List<User> findByStatus(@Param("status") int status);
3. Specification 动态条件(JPA Criteria)
// 6. 构建动态条件
public class UserSpecs {
public static Specification<User> hasUsername(String username) {
return (root, query, cb) ->
username == null ? null : cb.equal(root.get("username"), username);
}
public static Specification<User> ageGreaterThan(int age) {
return (root, query, cb) ->
cb.greaterThan(root.get("age"), age);
}
}
// 使用示例
List<User> users = userRepository.findAll(
Specification.where(UserSpecs.hasUsername("张三"))
.and(UserSpecs.ageGreaterThan(18))
);
4. QueryDSL 类型安全查询
// 7. QueryDSL条件组合
public List<User> searchUsers(String username, Integer minAge) {
QUser user = QUser.user;
BooleanBuilder builder = new BooleanBuilder();
if (StringUtils.isNotBlank(username)) {
builder.and(user.username.contains(username));
}
if (minAge != null) {
builder.and(user.age.goe(minAge));
}
return queryFactory.selectFrom(user)
.where(builder)
.fetch();
}
5. MyBatis 动态SQL(XML方式)
<!-- 8. MyBatis条件查询 -->
<select id="findByCondition" resultType="User">
SELECT * FROM users
<where>
<if test="username != null">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="minAge != null">
AND age >= #{minAge}
</if>
</where>
ORDER BY id DESC
</select>
实践案例:
// 综合示例:分页条件查询
@GetMapping("/users")
public Page<User> queryUsers(
@RequestParam(required = false) String username,
@RequestParam(defaultValue = "0") int minAge,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return userRepository.findAll(
(root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(username)) {
predicates.add(cb.like(root.get("username"), "%" + username + "%"));
}
if (minAge > 0) {
predicates.add(cb.ge(root.get("age"), minAge));
}
return cb.and(predicates.toArray(new Predicate[0]));
},
PageRequest.of(page, size, Sort.by("createTime").descending())
);
}
关键收获:
- 掌握了5种条件查询的实现方式及适用场景
- 理解了动态条件拼接的
Specification原理 - 实现了带分页的复合条件查询接口
遇到的问题:
- JPA方法名解析失败(解决:检查命名是否符合规范)
- QueryDSL的QClass未生成(解决:执行
mvn compile生成)

浙公网安备 33010602011771号