본문 바로가기
Project/ThreeMovie(영화리뷰및예약도우미)

JpaRepository join using QueryProjection with DTO(kotlin)

by HDobby 2023. 3. 13.

JpaRepository의 join을 사용하는 방법은 여러가지가 있습니다.

그 중 저는 QueryProjection을 이용한 방법을 사용했습니다.

 

코틀린 data class에서 QueryProjection을 사용하기 위해서는 아래와 같이 선언해주시면 됩니다.

data class MovieListDTO @QueryProjection constructor(
	val MovieId: String = "",
	...
)

 

MovieInfoController

@RestController
@RequestMapping("/api/movieinfo")
class MovieInfoController(
	val movieInfoService: MovieInfoServiceimpl,
	val movieCreatorService: MovieCreatorServiceimpl,
	val moviePreviewService: MoviePreviewServiceimpl
) {

	@GetMapping("/movielist")
	fun getMovieList(): List<MovieListDTO> {
		return movieInfoService.getMovieList()
	}
}

 

MovieInfoService

interface MovieInfoService {
	fun getMovieList(): List<MovieListDTO>
}

 

MovieInfoServiceImpl

@Service
class MovieInfoServiceimpl(
	val movieDataRepository: MovieInfoRepository,
	val movieInfoRepositorySupport: MovieInfoRepositorySupport,
) : MovieInfoService {
	override fun getMovieList(): List<MovieListDTO> {
		return movieInfoRepositorySupport.getMovieList()
	}
}

 

MovieInfo Entity

@Entity
@Table(name = "MovieInfo")
data class MovieInfo(
	@Id
	@Column(name = "MovieId")
	val MovieId: String = "",

	@Column(name = "Summary")
	val Summary: String = "",

	@Column(name = "NameKR")
	val NameKR: String = "",

	@Column(name = "NameEN")
	val NameEN: String = "",

	@Column(name = "ReleaseDate")
	val ReleaseDate: String? = "",

	@Column(name = "Poster")
	val Poster: String? = "",

	@Column(name = "Category")
	val Category: String = "",
)

 

MoviePreview Entity

@Entity
@Table(name = "MoviePreview")
data class MoviePreview(
	@Id
	@Column(name = "MovieId")
	val MovieId: String = "",

	@Column(name = "Steelcuts")
	val Steelcuts: String = "",

	@Column(name = "Trailer")
	val Trailer: String = "",
)

 

MovieListDTO

data class MovieListDTO @QueryProjection constructor(
	val MovieId: String = "",

	val NameKR: String = "",

	val NameEN: String = "",

	val Poster: String? = "",

	val Category: String = "",

	val Steelcuts: String = "",

	val Trailer: String = "",
)

 

MovieInfoRepositorySupport

@Repository
class MovieInfoRepositorySupport(
	val query: QueryDslConfig
) : QuerydslRepositorySupport(ShowTimeMovieInfo::class.java) {
	fun getMovieList(): List<MovieListDTO> {
		val moviePreview = QMoviePreview.moviePreview
		val movieInfo = QMovieInfo.movieInfo

		val movieList = query.jpaQueryFactory()
			.select(
				Projections.fields(
					MovieListDTO::class.java,
					movieInfo.MovieId,
					movieInfo.NameKR,
					movieInfo.NameEN,
					movieInfo.Poster,
					movieInfo.Category,
					moviePreview.Steelcuts,
					moviePreview.Trailer
				)
			)
			.from(movieInfo)
			.join(moviePreview)
			.on(movieInfo.MovieId.eq(moviePreview.MovieId))
			.fetch()
		println(movieList)
		return movieList
	}
}

 

결과

[{"nameEN":"Compartment Number 6","movieId":"6번 칸_20230308","nameKR":"6번 칸","poster":"https://t1.daumcdn.net/movie/c6d3448c3a42885e32485376b4ff4a89d02b6045","category":"[\"드라마\"]","trailer":"[https://tv.kakao.com/channel/462787/cliplink/435931672, https://tv.kakao.com/channel/462787/cliplink/435859624, https://tv.kakao.com/channel/462787/cliplink/435660055]","steelcuts":"[https://t1.daumcdn.net/movie/113b81e699919e86cdb710b1d3d121e434768529, https://t1.daumcdn.net/movie/6990996265f73d818276d385ace558ae54923c24, https://t1.daumcdn.net/movie/d3951a46341ace67b09c9394b514ce6e0121ab29, https://t1.daumcdn.net/movie/3f4b61ff3ebf2bb6e93c301a62ad4b2d85b130fc, https://t1.daumcdn.net/movie/50fe8fbd5aae4ca256fc814f8bee2fcd73e6bbd0, https://t1.daumcdn.net/movie/4b0ac60961a4d2e8aee65275821dcffcbb796192, https://t1.daumcdn.net/movie/8386172810ef155d0f0c8741847f26351477a036]"},{"nameEN":"Tar","movieId":"TAR 타르_20230222","nameKR":"TAR 타르"...
728x90

댓글