2017-06-06 73 views
-1

JPA类型安全的顺序查询

实体用户

@NamedQuery(name = “Users.findAll”,查询=“选择[u]来自用户的ü “)

使用方法如下:

Query query = em.createNamedQuery("Technologies.findByIsActive", Technologies.class); 
query.setFirstResult(technologiesTableModel.getLowItemIndex()); 
query.setMaxResults(technologiesTableModel.getPageRange().intValue()); 
List<Technologies> technologies = query.setParameter("isActive", 'Y').getResultList(); 

但我想排序这个结果动态。我有一个字符串包含我想要排序的列名称(字段内容来自请求)。我怎么能做到这一点,没有新的查询每个领域和方向,并键入安全(没有直接附加顺序的条款与字段名称)。

我的研究显示建议使用CriteriaQuery中(我无法找到例子与使用NamedQuery上述实体的定义),TypedQuery(我无法找到例如使用排序,只能用setFirstResultsetMaxResults。但我需要排序和分页)或JpaRepository(我无法找到具有良好说明的完整实施示例)。

那我要的是通过现场的名字我的数据进行排序(即我有一个字符串),之后寻呼它(与setFirstResultsetMaxResults)。我想这样做命名查询,我被定义(在实体类声明)和没有定义查询飞行或附加顺序子句查询结束与字符串连接。

编辑:

所有我需要的是一个很好的解释这是如何得来实现(与所有好的做法)。我不知道该怎么做。所有我尝试是:

  • 我的查询是在一个地方(大部分)
  • 字符串连接是不是好的做法创建查询。
+1

errm,由于NamedQuery是静态定义的,因此您可以静态(不是动态地)定义查询字符串。 Criteria或JPQL都支持您在运行时定义查询。任何JPA文档都会显示。 http://www.datanucleus.org/products/accessplatform_5_1/jpa/query.html#_criteria_api_ordering –

+0

命名查询不是动态的。看看这个主题https://stackoverflow.com/questions/22167730/dynamic-named-query-in-entity-class-using-jpql-example我会去与标准或SQL。由于JPA标准API不是最好的,QueryDSL可能是一个选项或Hibernate API本身。 – matthias

+0

如果不使用该JPA提供程序,或者您想要可移植性(即理智),则不会使用Hibernate API –

回答

0

我用案例条款解决我的问题。在我的实体,我添加orderClause领域,如:

public static final String orderClause = " order by " 
      + "case when :orderField = 'id' and :orderDirection = 'asc' then s.id else 0 end ASC, " 
      + "case when :orderField = 'id' and :orderDirection = 'desc' then s.id else 0 end DESC, " 
      + "case when :orderField = 'username' and :orderDirection = 'asc' then s.username else '' end ASC, " 
      + "case when :orderField = 'username' and :orderDirection = 'desc' then s.username else '' end DESC, " 
      + "s.id ASC"; 

,并在需要的地方像添加该字段结束命名查询:

@NamedQueries(
{ 
    @NamedQuery(name = "SysRoles.findAll", query = "SELECT s FROM SysRoles s" + SysRoles.orderClause), 
    @NamedQuery(name = "SysRoles.findByIsActive", query = "SELECT s FROM SysRoles s WHERE s.isActive = :isActive " + SysRoles.orderClause) 
}) 
public class SysRoles implements Serializable { 
    public static final String orderClause = " order by " 
     + "case when :orderField = 'id' and :orderDirection = 'asc' then s.id else 0 end ASC, " 
     + "case when :orderField = 'id' and :orderDirection = 'desc' then s.id else 0 end DESC, " 
     + "case when :orderField = 'username' and :orderDirection = 'asc' then s.username else '' end ASC, " 
     + "case when :orderField = 'username' and :orderDirection = 'desc' then s.username else '' end DESC, " 
     + "case when :orderField = 'isActive' and :orderDirection = 'asc' then s.isActive else '' end ASC, " 
     + "case when :orderField = 'isActive' and :orderDirection = 'desc' then s.isActive else '' end DESC, " 
     + "s.id ASC"; 
... 
} 

,我打电话给我的命名查询,如:

Query query = em.createNamedQuery("SysRoles .findAll", SysRoles.class); 
     //Pagination 
     query.setFirstResult(lowItemIndex); 
     query.setMaxResults(maxResults); 
List<SysRoles> sysUsers= query.setParameter("isActive", "Y") 
       //ditection of sorting 
       .setParameter("orderDirection", direction) 
       //name of sorting columns 
       .setParameter("orderField", orderByColumnName).getResultList(); 

更多关于按专栏名称排序和好解释可以找到here在博客asktom.oracle.com

有了这个解决方案,我们有一些丑陋的查询,但他们在一个地方,订购也在那里。