2017-06-06 10 views
-1

私はJPAタイプの安全な注文照会

エンティティありますユーザー

@NamedQuery(名前= "Users.findAll"、クエリ=「ユーザーからのuを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(); 

しかし、この結果の動的な並べ替えをしたいと思います。私は一つのの文字列を持っています。このフィールドには、並べ替える列の名前(フィールドの内容は要求から来ています)が含まれています。どのように私はフィールドと方向ごとに新しいクエリを使用せずにそれを行うことができます(フィールド名を持つ直接追加order by節なしで)安全な型を入力します。

私の研究ショーの提案は(私は、エンティティ上で定義されたNamedQueryを使用しての例を発見したことはできません)CriteriaQueryを使用するように、TypedQuery(私だけsetFirstResultメソッドはsetMaxResultsで、発注して例を発見したことはできません。しかし、私は並べ替えとページネーションの両方が必要です)またはJpaRepository(私は良い説明で完全な実装された例を見つけることができません)。私が欲しい

は、フィールドの名前で自分のデータをソートする(私は文字列のように持っていること)、その後、それ(とsetFirstResultメソッドはsetMaxResults)をページングすることです。私は(エンティティクラス宣言で)定義したNamedQueryで行い、はフライでクエリを定義しないか、ストリングの連結でクエリの最後にクエリを追加しません。

EDIT:

私に必要なのは、これが(すべてのグッドプラクティスで)実装する必要がどのように良い説明です。私はそれをどうやって行うのか考えていませんでした。私がしようすべては次のとおりです。

  • 私のクエリは一つの場所にあると
  • 文字列の連結は、クエリを作成することをお勧めではありません(それらのほとんど)。
+1

ERRMは、あなたが(ない動的)静的クエリ文字列を定義します。 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 criteria APIが一番いいわけではないので、QueryDSLはオプションでもHibernate APIでもかまいません。 – matthias

+0

そして、そのJPAプロバイダを使用していない場合、または移植性(つまり、sane)を望んでいる場合、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 01で見つけることができます。このソリューションで

は、我々は少し醜いクエリを持っていますが、彼らは一つの場所にあり、順序があるにもあります。 NamedQueryはその後、静的に定義されているので

関連する問題