我有
实体:用户
和
@NamedQuery(name =“Users.findAll”,query =“SELECT u FROM Users 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();
但我想对这个结果进行动态排序。我有一个 String ,其中包含我要排序的列名(字段内容来自请求)。如果没有针对每个字段和方向的新查询并且键入safe(如果没有带字段名称的直接附加order by子句),我该怎么做呢。
我的研究显示使用CriteriaQuery的建议(我找不到使用上面定义的 NamedQuery 实例),TypedQuery(我找不到订购示例,只能使用 setFirstResult 和 setMaxResults 。但我需要排序和分页)或JpaRepository(我找不到完整的实现示例和良好的描述)。
我想要的是按字段名称(我喜欢String)对数据进行排序,然后对其进行分页(使用 setFirstResult 和 setMaxResults )。我希望使用我定义的 NamedQuery (在实体类声明中)和不在运行时定义查询或附加order子句来查询以字符串连接结束。
修改
我需要的只是一个很好的解释如何实施(所有良好实践)。我不知道该怎么做。我尝试的只是:
答案 0 :(得分:0)
我使用 case 子句解决了我的问题。在我的实体中,我添加了 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();
有关按列名排序和良好解释的更多信息,请访问博客 asktom.oracle.com 中的here。
使用这个解决方案我们有一些丑陋的查询,但它们在一个地方,订购也在那里。