1. 概要

このチュートリアルでは、 Spring Data QuerydslWebサポートの第2部に進みます。ここでは、関連するエンティティと、HTTPを介してクエリを作成する方法に焦点を当てます。

パート1で使用したのと同じ構成に従って、Mavenベースのプロジェクトを作成します。 基本の設定方法については、元の記事を参照してください。

2. エンティティ

最初に、ユーザーとそのアドレスの間に関係を作成する新しいエンティティ(アドレス)を追加しましょう。シンプルにするためにOneToOne関係を使用しました。

したがって、次のクラスがあります。

@Entity 
public class User {

    @Id 
    @GeneratedValue
    private Long id;

    private String name;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "user") 
    private Address addresses;

    // getters & setters 
}
@Entity 
public class Address {

    @Id 
    @GeneratedValue
    private Long id;

    private String address;

    private String country;

    @OneToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "user_id") 
    private User user;

    // getters & setters
}

3. Springデータリポジトリ

この時点で、通常どおり、エンティティごとに1つずつSpringDataリポジトリを作成する必要があります。 これらのリポジトリにはQuerydsl構成があることに注意してください。

AddressRepository リポジトリを見て、フレームワーク構成がどのように機能するかを説明しましょう。

public interface AddressRepository extends JpaRepository<Address, Long>, 
  QuerydslPredicateExecutor<Address>, QuerydslBinderCustomizer<QAddress> {
 
    @Override 
    default void customize(QuerydslBindings bindings, QAddress root) {
        bindings.bind(String.class)
          .first((SingleValueBinding<StringPath, String>) StringExpression::eq);
    }
}

customize()メソッドをオーバーライドして、デフォルトのバインディングを構成します。 この場合、すべての String プロパティについて、デフォルトのメソッドバインディングをequalsにカスタマイズします。

リポジトリがすべて設定されたら、@RestControllerを追加してHTTPクエリを管理する必要があります。

4. クエリレストコントローラー

パート1では、Query @RestControlleruserリポジトリで説明しました。ここでは、それを再利用します。

また、addressテーブルを照会することもできます。 したがって、このために、同様のメソッドを追加します。

@GetMapping(value = "/addresses", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<Address> queryOverAddress(
  @QuerydslPredicate(root = Address.class) Predicate predicate) {
    BooleanBuilder builder = new BooleanBuilder();
    return addressRepository.findAll(builder.and(predicate));
}

これがどのように機能するかを確認するために、いくつかのテストを作成してみましょう。

5. 統合テスト

方法を証明するためのテストが含まれています Querydslは機能します。 このために、MockMvcフレームワークを使用してHTTPクエリをシミュレートしていますユーザーこのエンティティを新しいエンティティに参加させる: 住所。 したがって、クエリフィルタリングを行うことができるようになりました住所属性。

スペインに住むすべてのユーザーを取得しましょう。

/users?addresses.country=スペイン 

@Test
public void givenRequest_whenQueryUserFilteringByCountrySpain_thenGetJohn() throws Exception {
    mockMvc.perform(get("/users?address.country=Spain")).andExpect(status().isOk()).andExpect(content()
      .contentType(contentType))
      .andExpect(jsonPath("$", hasSize(1)))
      .andExpect(jsonPath("$[0].name", is("John")))
      .andExpect(jsonPath("$[0].address.address", is("Fake Street 1")))
      .andExpect(jsonPath("$[0].address.country", is("Spain")));
}

その結果、QuerydslはHTTP経由で送信された述語をマップし、次のSQLスクリプトを生成します。

select user0_.id as id1_1_, 
       user0_.name as name2_1_ 
from user user0_ 
      cross join address address1_ 
where user0_.id=address1_.user_id 
      and address1_.country='Spain'

6. 結論

要約すると、Querydslは動的クエリを作成するための非常に単純な代替手段をWebクライアントに提供することを確認しました。 このフレームワークのもう1つの強力な使用法。

パートIでは、1つのテーブルからデータを取得する方法を説明しました。 その結果、複数のテーブルを結合するクエリを追加できるようになり、Webクライアントが作成したHTTPリクエストを直接フィルタリングするエクスペリエンスが向上しました。

この例の実装は、GitHubプロジェクトを確認できます。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。