【JPA】JPQLクエリー--まとめ


先のブログではJPAについてマクロ的なまとめを行い、JSF+CDI+EJB+JPA(eclipselink)のプログラムを構築することにも成功しました.JPAで実体照会をしていたところ、JPQL文を書くことに戸惑い、改めてまとめました.
Part 1:JPQL基本使い方
一、QueryクエリーAPI
EMが提供するQueryの作成方法:
    createNamedQuery(String name)
    createNativeQuery(String sqlString)
    createNativeQuery(String sqlString, Class resultClass)
    createNativeQuery(String sqlString, String resultSetMapping)
    createQuery(String jpqlString)
二、パラメータ設定
    List getResultList()
    Object getSingleResult();//上記select文用
    int executeUpdate();//update、delete文用
    Query setFirstResult(int startPosition)
    Query setMaxResult(int maxResult)
三、JPQLを使用して手順を問い合わせる:
(1)EntityManagerによるQueryオブジェクトの作成
(2)パラメータが含まれている場合はsetParameter()
(3)ページングが必要な場合は、QueryのsetFirstResult()またはsetMaxResult()を呼び出す
(4)select文の場合、getResultList()またはgetSingleResult()を使用する.
四、クエリーの実行
P 460は1つのdemoでokであり,返された結果リストと2層forループ,最終的に値を取得し,内層ループにおける条件,selectの条件個数に注意する.
//ここで、基本的な使い方を説明します
Part 2:JPQL構文
一、from句のfrom後接エンティティ名を使用して、as別名を提案します.from後は複数のエンティティとは接続されません.一般的には、暗黙的な接続または明示的な接続によってデカルト積またはテーブル間接続を書くことができます.二、select句の使用
select p.name, p from Person as p
(1)selectクエリの戻り結果は一般にList集合であり、上述のように[String,Person]結果の配列形式集合(解析に2層のループが必要)を返す.
for(int i = 0; i < result.size(); i++)
{
   Object[] values = (Object[])result.get(i);
   System.out.println(values[0] + "-->" 
      + values[1]);
}
または:
for(int i = 0; i < result.size(); i++)
{
    Object[] row = (Object[])result.get(i);
    for(int j = 0; j < row.length; j++)
    {
       System.out.println(row[j]);
    }
}
(2)特殊な場合、select後にエンティティオブジェクトまたは属性を含む項目が1つしかない場合、クエリによって得られる集合要素はそのエンティティオブジェクトまたは属性です.
三、クエリーでコンストラクタを使用する
select new ClassTest(p.name, p.address) from Person as p
は、上述のように、ClassTestである集合リストを返す.オブジェクト(前提:ClassTestは、p.name、p.addressをパラメータとするコンストラクタをサポートします)、p.nameタイプがStringの場合.p.addressタイプがStringの場合、ClassTestには次のコンストラクタがあります.
ClassTest(String s1, String s2)
        
四、distinceを使用して同じレコードselectを排除した後、distinctと一緒に、エンティティに対してクエリーする時、distinct修飾を通じて、重複したクエリー結果を除去することができ、文は表示されない.
       
五、where句と条件式(1)共通演算子:数学、バイナリ比較、論理、inot inbetweenis nullis emptyis not emptymember ofmot member of.(2)likeオペレータ:
select name from Person where name like 'tom%'

上の演算子の機能はおおむねSQL文に似た演算子の機能と同じであり,SQLの経験をそのままJPQLに用いることができる.
六、JPQL関数を使ってJPQLの掌握に対して、必ずSQL文のようにして、同時に豊富な関数を掌握して、私达の问题を処理することを助けます.
一般的な関数:
(1)文字列関数
         concat(str1,str2)\substring(str,pos,len)\trim([leading|trailing|both] sub from str) 
(2)数学関数
         abs(math_expression)
 sqrt(math_express)
         mod(number,div)
         size(collection_expression)
(3)日付・時刻関数
         current_date\current_time\current_timestamp
七、マルチステートクエリ
たとえば、次の文があります.
select p.name from Person p
このクエリは、Personのすべてのインスタンスのname属性だけでなく、Personのサブクラスインスタンスのname属性もすべてクエリします.
継承関係のあるエンティティが親エンティティのプロパティをクエリーすると、子エンティティのnameプロパティが検出されます.
八、関連と接続
参考Part 3.
九、orderbyによる結果ソート
select p from Person as p order by p.name, p.age

十、JPQLクエリの集計関数
JPQLは、選択した属性に集約関数を使用することをサポートします.以下の5つがあります.
avg:属性平均値.
count:選択オブジェクトの数を統計します.
max:統計属性値の最大値.
min:統計属性値の最小値.
sum:属性値の合計を計算します.
十一、サブクエリの使用
クエリ結果セットは通常where句でフィルタ処理されますが、下位データベースでサブクエリがサポートされている場合は、JPQL文でサブクエリを使用して英語()で囲むことができます.次のようになります.
select fatcat from Cat as fatcat
	where fatcat.weight > (select avg(cat.weight) from DomesticCat cat)
JPQLサブクエリが複数行の結果セットを返す場合、any、allまたはsomeが、>、
十二、命名クエリー
JPAはAnnotationを使用してJPQLクエリー文を定義することをサポートし、AnnotationでJPQLクエリー文を定義する方法は名前付きクエリーです.JPAでは、名前付きクエリーを定義するために@NamedQuery、@NamedQueriesの2つのAnnotationが用意されています.たとえば、最近作ったduke-bookstoreプロジェクトでは、次のような使い方があります.
@Entity
@Table(name = "WEB_BOOKSTORE_BOOKS")
@NamedQuery(
        name = "findBooks",
        query = "SELECT b FROM Book b ORDER BY b.bookId")
public class Book implements Serializable {

    private static final long serialVersionUID = -4146681491856848089L;
    @Id
    @NotNull
    private String bookId;
    private String surname;
    private String firstname;
    private String title;
    private Double price;
    private Boolean onsale;
    private Integer calendarYear;
    private String description;
    private Integer inventory;

    public Book() {
    }

    public Book(String bookId, String surname, String firstname, String title,
            Double price, Boolean onsale, Integer calendarYear,
            String description, Integer inventory) {
        this.bookId = bookId;
        this.surname = surname;
        this.firstname = firstname;
        this.title = title;
        this.price = price;
        this.onsale = onsale;
        this.calendarYear = calendarYear;
        this.description = description;
        this.inventory = inventory;
    }
}
Entityレイヤで@NameQueryを直接使用してクエリー文を定義した後、ServiceImplレイヤで次のように呼び出されます.
public List getBooks() throws BooksNotFoundException {
    try {
        return (List) em.createNamedQuery("findBooks").getResultList();
    } catch (Exception ex) {
        throw new BooksNotFoundException(
                "Could not get books: " + ex.getMessage());
    }
}
em.createName Query(「
findBooks").getResultList()は、@Name Queryへの呼び出しを実現します.
 
十三、一括更新と一括削除
(1)一括更新:
update  set ... [Where where_conditions]
は、上述したように、一括更新された書き方フォーマットを実現している.
(2)一括削除:
delete from  [where where_conditions]
一括削除を実現する基本構文は、SQL構文に似ており、あまり紹介しません.
Part 3:JPQL one to one、one to many、many to manyについて
コンセプト:
(1)関係維持端:関係に対してCRUD操作を行う;外部キー記録の更新を担当し、関係が維持される側は外部キー記録を更新する権利がない.(one to manyが多い方、many to manyは中間関連表)(2)関係被維持端:MappedBy注釈を持ち、CRUD操作を行わず、関係を維持しない.
(3)分類:one to one、one to many、many to many‖一方向、双方向
詳細な分析:
JPQLエンティティマッピングの詳細については、次のブログを参照してください.
まとめ:
JPQLについては、上記の3つの角度から最初のまとめを行い、後で問題に遭遇した解答や詳細な紹介が続いています.