问题描述
我的项目中有很多动态查询,可能有 2 种方法可以构建动态查询。我已经在下面展示了它们,
- 有条件的地方
@Query("select c from Customer c where " +
" (:name IS NULL OR c.name LIKE %:name%) "+
"and (:email IS NULL OR c.email =:email) "+
"and (:genderIds IS NULL OR c.genderId IN (:genderIds) ) ")
List<Customer> findByParameters(@Param("name") String name,@Param("email") String email,@Param("genderIds") List<Integer> genderIds);
- 通过使用 If 条件,例如
public List<Customer> getCustomersNativeQueryConditional(RequestCustomer request) {
StringBuilder sb = new StringBuilder();
MapsqlParameterSource params = new MapsqlParameterSource ();
sb.append("select * from Customer c where 1=1 ");
Optional.ofNullable(request.getName())
.ifPresent(s->{
sb.append(" AND c.name LIKE :name");
params.addValue("name","%"+s+"%");
});
Optional.ofNullable(request.getEmail())
.ifPresent(s->{
sb.append(" AND c.email =:email ");
params.addValue("email",s);
});
Optional.ofNullable(request.getGenderIds())
.ifPresent(ids->{
sb.append(" AND c.genderId IN (:genderIds) ");
params.addValue("genderIds",ids);
});
return namedPrmJdbcTemplate.query(sb.toString(),params,BeanPropertyRowMapper.newInstance(Customer.class));
}
注意:第二种情况下的请求对象是一个POJO,
public class RequestCustomer {
private String name;
private String email;
private List<Integer> genderIds;
}
我真正想知道的是,在数据库和/或编码标准方面,哪一个更有效/更好。经验丰富的开发人员应该在精心设计的应用程序中使用哪一个?
解决方法
从性能的角度来看,只包含实际需要的参数通常要好得多。
一般来说,优化器很难在 or
子句中使用 where
。更具体地说,当不同列上存在 or
条件时,优化器在应用索引时可能会遇到问题。