java如何动态查询
动态查询的实现方法
在Java中实现动态查询通常涉及根据运行时条件构建查询语句,以下是几种常见方法:
使用JDBC动态拼接SQL
通过字符串拼接方式构建SQL语句,适合简单场景:
StringBuilder sql = new StringBuilder("SELECT * FROM users WHERE 1=1");
if (name != null) {
sql.append(" AND name = '").append(name).append("'");
}
if (age > 0) {
sql.append(" AND age = ").append(age);
}
// 执行查询...
使用PreparedStatement防止SQL注入
更安全的参数化查询方式:

List<Object> params = new ArrayList<>();
StringBuilder sql = new StringBuilder("SELECT * FROM products WHERE 1=1");
if (category != null) {
sql.append(" AND category = ?");
params.add(category);
}
if (minPrice > 0) {
sql.append(" AND price >= ?");
params.add(minPrice);
}
PreparedStatement stmt = connection.prepareStatement(sql.toString());
for (int i = 0; i < params.size(); i++) {
stmt.setObject(i + 1, params.get(i));
}
使用JPA Criteria API
面向对象的类型安全查询方式:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);
List<Predicate> predicates = new ArrayList<>();
if (username != null) {
predicates.add(cb.equal(root.get("username"), username));
}
if (activeOnly) {
predicates.add(cb.isTrue(root.get("active")));
}
query.where(predicates.toArray(new Predicate[0]));
return entityManager.createQuery(query).getResultList();
使用Spring Data JPA Specification
Spring提供的动态查询接口:

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {}
Specification<User> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (department != null) {
predicates.add(cb.equal(root.get("department"), department));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
List<User> users = userRepository.findAll(spec);
使用QueryDSL
类型安全的查询构建器:
QUser user = QUser.user;
BooleanBuilder builder = new BooleanBuilder();
if (nameFilter != null) {
builder.and(user.name.contains(nameFilter));
}
if (minAge > 0) {
builder.and(user.age.goe(minAge));
}
List<User> users = userRepository.findAll(builder);
使用MyBatis动态SQL
XML配置方式的动态查询:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="roles != null">
AND role IN
<foreach item="role" collection="roles" open="(" separator="," close=")">
#{role}
</foreach>
</if>
</where>
</select>
动态查询的注意事项
- 始终防范SQL注入攻击,优先使用参数化查询
- 复杂的动态查询应考虑使用专门的查询构建器
- 对于大量动态条件,建议采用设计模式如Builder模式来构建查询
- 性能敏感场景注意缓存常用查询模式






