Nac*_*tin 6 java jpa filter optional-parameters jpql
我得到了我想用 3 个可选参数(货币、数量和年份)过滤的硬币列表
如何将 JPQL 中的参数设置为可选?我不想做 9 个“if else”来检查它是否为空
我得到了使用 3 个可选参数过滤对象 Moneda(coin) 的函数 filtradoMonedas (filterCoins),但如果有一个空参数,它就不起作用。
如果不设置空参数,如果 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;
}
Run Code Online (Sandbox Code Playgroud)
在阅读了 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);
Run Code Online (Sandbox Code Playgroud)
请注意这里如何??,我使用 OR 语句基于我的参数可以呈现两种形式,FilterSuperAwesome 或 NULL 的实例。当为 NULL 时,条件始终为 True,就好像它不存在一样。
这在 JHipster 项目的 JpaRepository 类中工作得很好。
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9818 次 |
| 最近记录: |