Querydslサポートの追加 パーマリンク to "Querydslサポートの追加"

このTipは@omrzljakにより提出され、@arnaud-deprezにより更新されました

Spring Data のクエリでできることではクエリを作成するのに十分ではない場合があります。@Queryアノテーションや独自に書くこともできますが、私たちの中には、Querydslが提供するようなタイプセーフなクエリを書くのが好きな人もいます。

生成されたPredicateクラス パーマリンク to "生成されたPredicateクラス"

Querydslの重要な部分は、Predicateと呼ばれるクエリ用に生成されたドメインクラスです。spring-data-mongodbの場合、これらはJavaアノテーション後処理ツールによって生成されます。

Gradleプラグイン パーマリンク to "Gradleプラグイン"

spring-data-mongodbの設定をサポートするQuerydsl用のGradleプラグインもあります。

Mavenプラグイン パーマリンク to "Mavenプラグイン"

Maven用のプラグインもあります。Mavenの構成については、ドキュメントのMavenによるインテグレーションの章で詳しく説明されています。また、次の手順を実行する必要があります。

: org.slf4jはSpring Bootに含まれているので、依存関係に含めないでください。

変更 パーマリンク to "変更"

build.gradle パーマリンク to "build.gradle"

build.gradleで、依存関係をQuerydsl pluginに追加します。

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.9"
    }
}

apply from: 'gradle/querydsl.gradle'

gradle.propertiesで使用するQuerydsl versionを定義してください。

querydsl_version=4.1.4

Then create a the file gradle/querydsl.gradle with

apply plugin: "com.ewerk.gradle.plugins.querydsl"

sourceSets {
    main {
        java {
            srcDir "$buildDir/generated/source/apt/main"
        }
    }
}

querydsl {
    // we use mongodb
    springDataMongo = true
    querydslSourcesDir = "$buildDir/generated/source/apt/main"
}

dependencies {
    compile "com.querydsl:querydsl-mongodb:${querydsl_version}"
    compileOnly "com.querydsl:querydsl-apt:${querydsl_version}"
}

MongoDBを使用していますが、Querydslプラグインはその他のオプションもサポートしています。

gradle buildを実行すると、次のような出力が表示されます。 Note: Generating net.jogat.names.domain.QName for [net.jogat.names.domain.Name]

@Documentでアノテートされたドメインクラスごとに、Querydslプラグインは1つのPredicateクラスを生成します。

リポジトリクラスの変更 パーマリンク to "リポジトリクラスの変更"

例えばNameのようなドメインクラスがある場合は、NameRepositoryクラスもあります。すべてのリポジトリクラスをQueryDslPredicateExecutorから拡張するように変更する必要があります。

public interface NameRepository extends MongoRepository<Name, String>, QueryDslPredicateExecutor<Name> {

これにより、Querydslをサポートする追加のメソッドでリポジトリクラスが拡張されます。 (参考 )

Webサポート パーマリンク to "Webサポート"

パラメータ化されたリクエストをサポートするために残りのコントローラを拡張するには、org.springframework.data.querydsl.binding.QuerydslPredicateでアノテーションが付けられたcom.mysema.query.types.Predicateをメソッドパラメータに追加する必要があります。

@RestController
@RequestMapping("/api")
class NameResource {

    private final NameRepository nameRepository;
    
    public NameResource(NameRepository nameRepository) {
        this.nameRepository = nameRepository;
    }

    @RequestMapping(value = "/names",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public ResponseEntity<List<Name>> getAllNames(@QuerydslPredicate(root = Name.class) Predicate predicate,
                                                    Pageable pageable) {
        log.debug("REST request to get a page of Name");
        Page<Name> page = nameRepository.findAll(predicate, pageable);
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/names");
        return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
    }
    ...
}

また、NameResourceIntTestではQuerydslPredicateArgumentResolverをサポートする必要があります。

public class NameResourceIntTest {
    ...
    @Autowired
    private NameRepository nameRepository;
    @Autowired
    private QuerydslPredicateArgumentResolver querydslPredicateArgumentResolver;

    @PostConstruct
    public void setup() {
        MockitoAnnotations.initMocks(this);
        NameResource nameResource = new nameResource(nameRepository);
        this.restNameMockMvc = MockMvcBuilders.standaloneSetup(nameResource)
            .setCustomArgumentResolvers(pageableArgumentResolver, querydslPredicateArgumentResolver)
            .setMessageConverters(jacksonMessageConverter).build();
    }
    ...
}

詳細については、ドキュメントを参照してください。

タイプセーフなクエリを作成する パーマリンク to "タイプセーフなクエリを作成する"

GradleまたはMavenプラグインは、Name.classのクエリを記述するために使用できるクラスQNameを生成します。次にJavaの例を示します。

QName name = QName.name;

// リスト"categorie"に文字列"TOP_EVER"が含まれるすべての名前をカウントします
nameRepository.count(name.categories.contains("TOP_EVER"));