2014-03-04 25 views
0

我有如下的命名查询;使用JPQL的实体类中的动态命名查询示例

@NamedQuery(name = "MyEntityClass.findSomething", query = "SELECT item FROM MyTable mytbl") 

现在我要动态排序条款追加到该查询(基于UI参数)

我能使用JPQL做同样的(比如如何设置一个动态的ORDER BY的一个例子实体类)

我已经尝试过使用CriteriaQuery,但现在正在寻找JPQL实现。

回答

3

NamedQueries根据定义不是动态的,以编程方式更改它们是不正确的。

所以要走的路是创建一个JPQL查询(而不是命名查询)是这样的:

TypedQuery<MyEntity> query = em.createdQuery("SELECT item FROM MyEntity item ORDER BY "+sortingCol, MyEntity.class); 

在另一方面,如果你真的想使用的命名查询,你可以这样做下列方式:

@NamedQuery(name = "MyEntityClass.findSomething", query = MyEntity.NAMED_QUERY) 
@Entity 
public class MyEntity { 
    public static final NAMED_QUERY= "SELECT item FROM MyTable mytbl"; 
    //+your persistent fields/properties... 
} 
//and later in your code 
TypedQuery<MyEntity> query = entityManager.createQuery(MyEntity.NAMED_QUERY + " ORDER BY " + sortingCol, MyEntity.class); 
1

@NameQuery

  • 持久性提供ç在部署时将命名查询从JPQL转换为SQL
  • 到目前为止,没有任何功能可以在运行时用@NameQuery批注创建/更新查询。
  • 另一方面,您可以使用Reflection APIchange the annotation value at runtime。我认为这不是解决方案,也不是你想要的。

em.createQuery()

  • 持久性提供转换的动态查询从每一个被调用时JPQLSQL
  • 使用动态查询的主要优点是查询可以创建依赖于用户输入。
1

的JPA 2.1

补充作为JPA 2.1的可以编程的方式定义命名查询。
这可以使用entityManagerFactory.addNamedQuery(String name, Query)来实现。

实施例:

Query q = this.em.createQuery("SELECT a FROM Book b JOIN b.authors a WHERE b.title LIKE :title GROUP BY a"); 
this.em.getEntityManagerFactory().addNamedQuery("selectAuthorOfBook", q); 
// then use like any namedQuery 

参考here

这可以是有用的,例如,如果你有定义为应用程序参数的OrderBy字段。因此,当应用程序启动时或第一次运行查询时,可以使用定义的OrderBy字段定义NamedQuery。另一方面,如果您的OrderBy可以随时更改(或更改很多),那么您需要动态查询而不是NamedQuery(静态)。每次(通过性能)都不值得(重新)创建一个NamedQuery。