【JPA/Querydsl】必要なカラムだけDTOにマッピングする(Projections.constructor)
|
queryDSLで「SELECT * FROM…」するのではなく、必要なカラムだけ取得する方法をお伝えします。
クエリチューニングの一環としてでSELECTする対象を絞り込む時(Key LookUpを減らして実行計画改善する時とか)に便利なTipになってます!
[st-myblock id=”447″]
解決したい課題
- JPA + queryDSLで必要なカラムだけ取得したい
- その際、@Entityクラスではなく、自分で作ったDTO的なクラスに結果をマッピングしたい
そもそもqueryDSLとは
JPA+HibernateでSQLを実装する際、型安全な実装を可能にしてくれるライブラリ。
Querydsl – Unified Queries for Java
結論:Projections.constructorを使う
Projectiosns.constructor
というメソッドによって、DTOに結果をマッピングします。
TABLE
↓このbook
テーブルに対して、release_date以外のデータを取ってくることを想定します。
CREATE TABLE book (
id VARCHAR(255) PRIMARY KEY,
title VARCHAR(255) NOT NULL,
author VARCHAR(255) NOT NULL,
release_date DATETIME NOT NULL //この行は今回取得したくない!!!
);
TABLEクラス
import java.time.LocalDateTime
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.JoinColumn
import javax.persistence.OneToMany
import javax.persistence.Table
@Entity @Table(name = "book")
class BookEntity(
@Id
var id: String? = null,
val title: String? = null,
val author: String? = null,
val releaseDate: LocalDateTime? = null,
)
DTOクラス
class BookDto(
val id: String,
val title: String,
val author: String,
)
クエリメソッド
select句の中にProjections.constructorメソッドを入れて、DTOにマッピングします。
import com.querydsl.core.types.Projections
import com.querydsl.jpa.impl.JPAQueryFactory
import com.sample.infra.jpa.entity.QBookEntity //自動生成されるQEntity
import com.sample.usecase.query.BookDto
val queryFactory: JPAQueryFactory = JPAQueryFactory(entityManager); //entityManagerはjavax.persistence.EntityManager
val book = QBookEntity.bookEntity //自動生成されるQEntity
val result = queryFactory.select(
Projections.constructor(
BookDto::class.java,
book.id,
book.author,
book.title,
)
).from(book).where(book.id.eq(id)).fetchOne()
公式ドキュメントも参考にしてみてください!
https://javadoc.io/doc/com.querydsl/querydsl-core/4.0.5/com/querydsl/core/types/Projections.html