1. 概要

以前、ApacheCayenneの使用を開始する方法に焦点を当ててきました。

この記事では、ORMを使用して単純で高度なクエリを作成する方法について説明します。

2. 設定

セットアップは、前の記事で使用したものと同様です。

さらに、各テストの前に3人の作成者を保存し、最後にそれらを削除します。

  • ポールザビエル
  • ポールスミス
  • ヴィッキーサラ

3. ObjectSelect

簡単に始めて、「Paul」を含む名前を持つすべての作成者を取得する方法を見てみましょう。

@Test
public void whenContainsObjS_thenWeGetOneRecord() {
    List<Author> authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.contains("Paul"))
      .select(context);

    assertEquals(authors.size(), 1);
}

次に、作成者の名前列に大文字と小文字を区別しないLIKEタイプのクエリを適用する方法を見てみましょう。

@Test
void whenLikeObjS_thenWeGetTwoAuthors() {
    List<Author> authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.likeIgnoreCase("Paul%"))
      .select(context);

    assertEquals(authors.size(), 2);
}

次に、 endsWith()式は、一致する名前が1人の作成者のみであるため、1つのレコードのみを返します。

@Test
void whenEndsWithObjS_thenWeGetOrderedAuthors() {
    List<Author> authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.endsWith("Sarra"))
      .select(context);
    Author firstAuthor = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(firstAuthor.getName(), "Vicky Sarra");
}

より複雑なのは、名前がリストにある著者にクエリを実行することです。

@Test
void whenInObjS_thenWeGetAuthors() {
    List names = Arrays.asList(
      "Paul Xavier", "pAuL Smith", "Vicky Sarra");
 
    List<Author> authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.in(names))
      .select(context);

    assertEquals(authors.size(), 3);
}

nin は反対で、ここでは「Vicky」のみが結果に表示されます。

@Test
void whenNinObjS_thenWeGetAuthors() {
    List names = Arrays.asList(
      "Paul Xavier", "pAuL Smith");
    List<Author> authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.nin(names))
      .select(context);
    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "Vicky Sarra");
}

次の2つのコードは、どちらも同じパラメーターで同じタイプの式を作成するため、同じであることに注意してください。

Expression qualifier = ExpressionFactory
  .containsIgnoreCaseExp(Author.NAME.getName(), "Paul");
Author.NAME.containsIgnoreCase("Paul");

ExpressionおよびExpressionFactoryクラスで使用可能な式のリストを次に示します。

  • likeExp :LIKE式を作成するため
  • likeIgnoreCaseExp :LIKE_IGNORE_CASE式の作成に使用されます
  • containsExp :文字列内の任意の場所に一致するパターンを持つLIKEクエリの式
  • containsIgnoreCaseExp containsExp と同じですが、大文字と小文字を区別しないアプローチを使用します
  • startupsWithExp :パターンは文字列の先頭と一致する必要があります
  • startupsWithIgnoreCaseExp startupsWithExp と似ていますが、大文字と小文字を区別しないアプローチを使用しています
  • endsWithExp :文字列の終わりに一致する式
  • endsWithIgnoreCaseExp :大文字と小文字を区別しないアプローチを使用して文字列の末尾に一致する式
  • expTrue :ブールtrue式の場合
  • expFalse :ブールfalse式の場合
  • andExp および演算子を使用して2つの式をチェーンするために使用されます
  • orExp または演算子を使用して2つの式を連鎖させる

記事のコードソースには、さらに多くの書面によるテストがあります。Githubリポジトリを確認してください。

4. SelectQuery

これは、ユーザーアプリケーションで最も広く使用されているクエリタイプです。 SelectQuery は、SQL構文のように機能するシンプルで強力なAPIを記述しますが、Javaオブジェクトとメソッドに続いて、より複雑な式を構築するためのビルダーパターンを使用します。

ここでは、 Expression (式を作成するため)別名修飾子と Ordering (結果を並べ替える)クラスの両方を使用してクエリを作成し、次にネイティブSQLに変換する式言語について説明します。 ORMによる。

これが実際に動作することを確認するために、いくつかの式を作成してデータを並べ替える方法を実際に示すいくつかのテストをまとめました。

LIKEクエリを適用して、「Paul」のような名前の作成者を取得しましょう。

@Test
void whenLikeSltQry_thenWeGetOneAuthor() {
    Expression qualifier 
      = ExpressionFactory.likeExp(Author.NAME.getName(), "Paul%");
    SelectQuery query 
      = new SelectQuery(Author.class, qualifier);
    
    List<Author> authorsTwo = context.performQuery(query);

    assertEquals(authorsTwo.size(), 1);
}

つまり、クエリ( SelectQuery )に式を指定しない場合、結果はAuthorテーブルのすべてのレコードになります。

containsIgnoreCaseExp 式を使用して同様のクエリを実行し、文字の大文字と小文字に関係なく、Paulを含む名前のすべての作成者を取得できます。

@Test
void whenCtnsIgnorCaseSltQry_thenWeGetTwoAuthors() {
    Expression qualifier = ExpressionFactory
      .containsIgnoreCaseExp(Author.NAME.getName(), "Paul");
    SelectQuery query 
      = new SelectQuery(Author.class, qualifier);
    
    List<Author> authors = context.performQuery(query);

    assertEquals(authors.size(), 2);
}

同様に、大文字と小文字を区別しない方法で「Paul」を含む名前( containsIgnoreCaseExp )と、文字hで終わる名前( endsWithExp )の作成者を取得しましょう。

@Test
void whenCtnsIgnorCaseEndsWSltQry_thenWeGetTwoAuthors() {
    Expression qualifier = ExpressionFactory
      .containsIgnoreCaseExp(Author.NAME.getName(), "Paul")
      .andExp(ExpressionFactory
        .endsWithExp(Author.NAME.getName(), "h"));
    SelectQuery query = new SelectQuery(
      Author.class, qualifier);
    List<Author> authors = context.performQuery(query);

    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "pAuL Smith");
}

昇順は、Orderingクラスを使用して実行できます。

@Test
void whenAscOrdering_thenWeGetOrderedAuthors() {
    SelectQuery query = new SelectQuery(Author.class);
    query.addOrdering(Author.NAME.asc());
 
    List<Author> authors = query.select(context);
    Author firstAuthor = authors.get(0);

    assertEquals(authors.size(), 3);
    assertEquals(firstAuthor.getName(), "Paul Xavier");
}

ここでは、 query.addOrdering(Author.NAME.asc())を使用する代わりに、 SortOrderクラスを使用して昇順を取得することもできます。

query.addOrdering(Author.NAME.getName(), SortOrder.ASCENDING);

比較的降順があります:

@Test
void whenDescOrderingSltQry_thenWeGetOrderedAuthors() {
    SelectQuery query = new SelectQuery(Author.class);
    query.addOrdering(Author.NAME.desc());

    List<Author> authors = query.select(context);
    Author firstAuthor = authors.get(0);

    assertEquals(authors.size(), 3);
    assertEquals(firstAuthor.getName(), "pAuL Smith");
}

前の例で見たように、この順序を設定する別の方法は次のとおりです。

query.addOrdering(Author.NAME.getName(), SortOrder.DESCENDING);

5. SQLTemplate

SQLTemplate は、オブジェクトスタイルのクエリを使用しないためにCayenneで使用できる代替手段の1つでもあります。

SQLTemplate を使用したビルドクエリは、いくつかのパラメーターを使用したネイティブSQLステートメントの記述に直接関連しています。 いくつかの簡単な例を実装しましょう。

各テスト後にすべての作成者を削除する方法は次のとおりです。

@After
void deleteAllAuthors() {
    SQLTemplate deleteAuthors = new SQLTemplate(
      Author.class, "delete from author");
    context.performGenericQuery(deleteAuthors);
}

記録されたすべての作成者を検索するには、SQLクエリ select * from Author を適用するだけで、正確に3人の作成者が保存されているため、結果が正しいことが直接わかります。

@Test
void givenAuthors_whenFindAllSQLTmplt_thenWeGetThreeAuthors() {
    SQLTemplate select = new SQLTemplate(
      Author.class, "select * from Author");
    List<Author> authors = context.performQuery(select);

    assertEquals(authors.size(), 3);
}

次に、「VickySarra」という名前の作成者を取得しましょう。

@Test
void givenAuthors_whenFindByNameSQLTmplt_thenWeGetOneAuthor() {
    SQLTemplate select = new SQLTemplate(
      Author.class, "select * from Author where name = 'Vicky Sarra'");
    List<Author> authors = context.performQuery(select);
    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "Vicky Sarra");
}

6. EJBQLQuery

次に、カイエンでJava PersistenceAPIを採用するための実験の一環として作成されたEJBQLQuery、を介してデータをクエリしてみましょう。

ここでは、クエリはパラメータ化されたオブジェクトスタイルで適用されます。 いくつかの実用的な例を見てみましょう。

まず、保存されているすべての作成者の検索は次のようになります。

@Test
void givenAuthors_whenFindAllEJBQL_thenWeGetThreeAuthors() {
    EJBQLQuery query = new EJBQLQuery("select a FROM Author a");
    List<Author> authors = context.performQuery(query);

    assertEquals(authors.size(), 3);
}

「VickySarra」という名前で著者をもう一度検索してみましょう。ただし、EJBQLQueryを使用して検索します。

@Test
void givenAuthors_whenFindByNameEJBQL_thenWeGetOneAuthor() {
    EJBQLQuery query = new EJBQLQuery(
      "select a FROM Author a WHERE a.name = 'Vicky Sarra'");
    List<Author> authors = context.performQuery(query);
    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "Vicky Sarra");
}

さらに良い例は、作成者を更新することです。

@Test
void whenUpdadingByNameEJBQL_thenWeGetTheUpdatedAuthor() {
    EJBQLQuery query = new EJBQLQuery(
      "UPDATE Author AS a SET a.name "
      + "= 'Vicky Edison' WHERE a.name = 'Vicky Sarra'");
    QueryResponse queryResponse = context.performGenericQuery(query);

    EJBQLQuery queryUpdatedAuthor = new EJBQLQuery(
      "select a FROM Author a WHERE a.name = 'Vicky Edison'");
    List<Author> authors = context.performQuery(queryUpdatedAuthor);
    Author author = authors.get(0);

    assertNotNull(author);
}

列を選択するだけの場合は、このクエリ「selecta.name FROMAuthora」を使用する必要があります。 Github の記事のソースコードには、さらに多くの例があります。

7. SQLExec

SQLExec も、CayenneのバージョンM4から導入された新しい流暢なクエリAPIです。

単純な挿入は次のようになります。

@Test
void whenInsertingSQLExec_thenWeGetNewAuthor() {
    int inserted = SQLExec
      .query("INSERT INTO Author (name) VALUES ('Baeldung')")
      .update(context);

    assertEquals(inserted, 1);
}

次に、著者の名前に基づいて著者を更新できます。

@Test
void whenUpdatingSQLExec_thenItsUpdated() {
    int updated = SQLExec.query(
      "UPDATE Author SET name = 'Baeldung' "
      + "WHERE name = 'Vicky Sarra'")
      .update(context);

    assertEquals(updated, 1);
}

詳細については、ドキュメントをご覧ください。

8. 結論

この記事では、カイエンを使用して単純でより高度なクエリを作成するいくつかの方法について説明しました。

いつものように、この記事のソースコードはGitHubにあります。