如何将JPQL中的参数设置为可选参数?我不想做9“if else”来检查它是否为null
我得到了函数filtradoMonedas(filterCoins),它使用3个可选参数过滤对象Moneda(硬币),但如果有空参数则无效。
如果不设置空参数,如果cantidad或ano是“”返回错误查询的异常,这只能正常工作。只想把它作为一个可选项。继承人的方法:
public List<Moneda> filtradoMonedas(Divisa divisa, BigDecimal cantidad,
BigDecimal ano){
EntityManager em = getEntityManager();
Query consulta = em.createQuery("SELECT m FROM Moneda m "
+ "WHERE m.divisa = :divisa "
+ "AND m.cantidad= :cantidad "
+ "AND m.ano = :ano");
consulta.setParameter("divisa", divisa);
consulta.setParameter("cantidad", cantidad);
consulta.setParameter("ano", ano);
List<Moneda> filtradoMonedas = (List<Moneda>) consulta.getResultList();
// sincronizar los objetos devueltos con la base de datos
for (Moneda m : filtradoMonedas) {
em.refresh(m);
}
em.close();
return filtradoMonedas;
}
答案 0 :(得分:1)
JPQL不支持可选参数。
实际上你应该认为参数不是可选的,而是条件是可选的。这个想法将引导您创建“动态”查询。这样就会引导您接下来从JPQL切换到Criteria API。这将导致你写这样的东西:
// Actually can be generated during build, and thus can be ommited
@StaticMetamodel(Moneda.class)
abstract class Moneda_ {
public static volatile SingularAttribute<Moneda, BigDecimal> cantidad;
public static volatile SingularAttribute<Moneda, Divisia> divisia;
public static volatile SingularAttribute<Moneda, BigDecimal> ano;
}
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Moneda> cq = cb.createQuery(Moneda.class);
final Root<Moneda> root = cq.from(Moneda.class);
Set<Predicate> predicates = new HashSet<>(3);
if (cantidad != null) {
predicates.add(cb.equal(root.get(Moneda_.cantidad), cantidad));
}
if (ano != null) {
predicates.add(cb.equal(root.get(Moneda_.ano), ano));
}
if (divisia != null) {
predicates.add(cb.equal(root.get(Moneda_.divisia), divisia));
}
cq.where(predicates.toArray(new Predicate[predicates.size()]));
em.createQuery(cq).getResultList();
// and do whatever you want
答案 1 :(得分:1)
在阅读了Ilya Dyoshin的评论和背后的精明思想之后,“您应该认为参数不是可选的,而条件是可选的”。我决定通过使用带有@Query注释的JPQL来实现自己的方式,并创建一个效果很好的动态SQL查询。
关键是应用一些SQL逻辑使条件成为可选条件而不是参数:
@Query("SELECT a " +
"FROM amazing " +
"WHERE (:filterSuperAwesome IS NULL " +
"OR a.filterSuperAwesome = :filterSuperAwesome)");
List<FilterSuperAwesome> filterAwesomeORSuperAwesome(
@Param("filterSuperAwesome ") FilterSuperAwesome filterSuperAwesome);
请注意,在这里,我基于我的参数可以呈现两种形式(FilterSuperAwesome或NULL实例)的事实使用OR语句。如果为NULL,则条件始终为True,就好像不存在一样。
这在JHipster项目的JpaRepository类中正常工作。