可选参数jpa 2.1 [英] optional parameters jpa 2.1

查看:125
本文介绍了可选参数jpa 2.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这堂课

@Entity
public class Message {

  @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
  private long id;

  @Column( nullable = false )
  private String mobile;

  @Column( nullable = false )
  private String message;

  @Column( nullable = false )
  private Lang lang;

  @Column( nullable = false )
  private int status;

  @Column( nullable = false )
  private Calendar creationDate;
  ...
}

,我希望能够使用表格中的可选参数查询表.我正在使用JPA 2.1和Hibernate.有没有没有多个查询语句或没有将我的应用程序紧密耦合到休眠或我正在使用的特定数据库的方法?

and I would like to be able to query the table with optional parameters from a form. I'm using JPA 2.1 and Hibernate. Is there way to do this without multiple query statements or without tightly coupling my application to hibernate or the specific database that i'm using?

这是我使用的表格:

<form action="${pageContext.request.contextPath}/search">
<label>From</label>
<input type="datetime" placeholder="dd/mm/yy hh/mm" name="from" required> 
<label>To</label>
<input type="datetime" placeholder="dd/mm/yy hh/mm" name="to" required> 
<select name="lang">
    <option value="english">English</option>
    <option value="arabic">Arabic</option>
</select>
<input type="tel" placeholder="Recipient" name="recipient">
<select name="status">
    <option value="new">New</option>
    <option value="picked">Picked</option>
    <option value="sent">Sent</option>
    <option value="rejected">Rejected</option>
</select>
<input type="submit" value="Search">

UPDATE ::::::::::::::::::::::::::::

UPDATE::::::::::::::::::::::::::::

我尝试过:

    public List<Message> getMessages(Calendar fromDate, Calendar toDate, String lang, String recipient, String status) {
    /*TypedQuery<Message> query = em.createQuery(
            "SELECT e FROM Message e WHERE e.creationDate BETWEEN :fromDate AND :toDate", Message.class);
    query.setParameter("fromDate", fromDate);
    query.setParameter("toDate", toDate);
    List<Message> list = query.getResultList();
    return list;*/

    List<Predicate> predicates = new ArrayList<>();

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Message> query = cb.createQuery(Message.class);
    Root<Message> root = query.from(Message.class);

    predicates.add(cb.between(root.get("creationDate"), fromDate, toDate));

    if (lang != null && !lang.equalsIgnoreCase("any")) {
           predicates.add(cb.equal(root.get("lang"), lang));
        }

    if (recipient != null && !recipient.equals("")) {
           predicates.add(cb.equal(root.get("mobile"), recipient));
        }

    if (status != null && !status.equalsIgnoreCase("any")) {
           predicates.add(cb.equal(root.get("mobile"), recipient));
        }

    query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
    List<Message> list = em.createQuery(query).getResultList();

    return list;
}

但出现以下错误:

java.lang.IllegalArgumentException: Parameter value [0] did not match expected type [entity.Lang (n/a)]
at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:897)
at org.hibernate.jpa.internal.QueryImpl.access$000(QueryImpl.java:61)
at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:235)
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:638)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:163)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:32)
at org.hibernate.jpa.criteria.compile.CriteriaCompiler$1$1.bind(CriteriaCompiler.java:109)
at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:369)
at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:130)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:699)
at dao.MessageDAO.getMessages(MessageDAO.java:63)

推荐答案

简短的回答:是的.您无需使用特定于休眠的类来构建满足您需求的查询.

Short answer: yes. You do not need to use hibernate-specific classes to build a query that fulfills your needs.

但是,您可能需要在构建查询之前过滤掉可选参数. 如果telnull/empty,则您可能不想在查询中使用它.因此,请勿将其添加到查询中. 查看 Java EE持久性教程

However, you may want to filter out your optional parameters before building your query. If tel is null/empty you probably don't want to have it in your query. So just don't add it to the query. Look at the Java EE persistence tutorial and the CriteriaBuilder javadoc to build your TypedQuery the way you need it.

伪代码(显然未经测试...但是希望您能理解):

Pseudo code (clearly untested... but I hope you get the idea):

List<Predicate> predicates = ...
CriteriaBuilder cb = ...
Root<?> table = ...
if (isNotBlank(tel)) {
   predicates.add(cb.equal(table.get("tel"), tel));
}
if (isNotBlank(...)) {
   predicates.add(cb.like(table.get("..."), ...));
}
...
query.where(cb.and(predicates.toArray(Predicate[]::new)));

也许还有以下帮助:真正的动态JPA CriteriaBuilder

这篇关于可选参数jpa 2.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆