我有这堂课
@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.criteriapile.CriteriaCompiler$1$1.bind(CriteriaCompiler.java:109) at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:369) at org.hibernate.jpa.criteriapile.CriteriaCompilerpile(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.
但是,您可能需要在构建查询之前过滤掉可选参数. 如果tel是null/empty,则您可能不想在查询中使用它.因此,请勿将其添加到查询中. 查看 Java EE持久性教程和 CriteriaBuilder javadoc 以所需的方式构建TypedQuery它.
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
发布评论