Closed WonHyeongCho closed 10 months ago
안녕하세요.
여러가지 방법이 있을 수 있습니다. 아래 문서를 참고해주세요. https://kotlin-jdsl.gitbook.io/docs/jpql-with-kotlin-jdsl/entities#alias
예제로 아래와 같은 2개의 형태를 만들어볼 수 있습니다.
authorRepository.findAll {
val authorA = entity(Author::class, "authorA")
val authorB = entity(Author::class, "authorB")
select<Tuple>(
entity(BookAuthor::class),
authorA(Author::name),
authorB(Author::name),
).from(
entity(BookAuthor::class),
join(authorA).on(path(BookAuthor::authorId).equal(authorA.path(Author::authorId))),
join(authorB).on(path(BookAuthor::authorId).equal(authorB.path(Author::authorId))),
)
}
authorRepository.findAll {
val authorA = entity(Author::class, "authorA")
val authorB = entity(Author::class, "authorB")
select<Tuple>(
entity(BookAuthor::class),
authorA(Author::name),
authorB(Author::name),
).from(
entity(BookAuthor::class),
join(entity(Author::class))
.on(path(BookAuthor::authorId).equal(authorA.path(Author::authorId)))
.alias(authorA),
join(entity(Author::class))
.on(path(BookAuthor::authorId).equal(authorB.path(Author::authorId)))
.alias(authorB),
)
}
두 쿼리 모두 아래의 JPQL로 랜더링 됩니다.
SELECT
BookAuthor,
authorA.name,
authorB.name
FROM
BookAuthor AS BookAuthor
INNER JOIN Author AS authorA ON BookAuthor.authorId = authorA.authorId
INNER JOIN Author AS authorB ON BookAuthor.authorId = authorB.authorId
답변해주셔서 감사합니다!
혹시 JDSL 에서 쿼리를 재사용할 수 있을까요?
mybatis 의
아 태그를 적어주셔서 안 보였군요. <sql>
, <include>
와 비슷한 기능도 가능합니다.
어떻게 코드를 재활용할지는 각자의 스타일이 달라서 제가 말씀드리기 어렵지만 제가 추천드리는 방법은 우리 팀에서 쓸 DSL
을 정의하는 것입니다.
자세한 내용은 아래를 참고해주세요. https://kotlin-jdsl.gitbook.io/docs/jpql-with-kotlin-jdsl/custom-dsl#dsl
예를 들면 아래처럼 나만의 Jpql 클래스를 정의한 뒤에
class BookJpql : Jpql() {
companion object Constructor : JpqlDsl.Constructor<BookJpql> {
override fun newInstance(): BookJpql = BookJpql()
}
fun Path<BookPrice>.greaterThan(price: Int): Predicate {
return this@greaterThan.path(BookPrice::value).greaterThan(BigDecimal.valueOf(price.toLong()))
}
fun Entity<Book>.salePriceBetween(min: Int, max: Int): Predicate {
return this@salePriceBetween.path(Book::salePrice)(BookPrice::value).between(
BigDecimal.valueOf(min.toLong()),
BigDecimal.valueOf(max.toLong()),
)
}
}
이를 아래처럼 사용할 수 있습니다.
bookRepository.findAll(BookJpql) {
select(
entity(Book::class),
).from(
entity(Book::class),
).whereAnd(
entity(Book::class)(Book::price).greaterThan(100),
entity(Book::class).salePriceBetween(100, 200),
)
}
이런 식으로 만들면 코드 중복 및 조금 더 도메인 특화된 DSL을 만들 수 있고, 메소드이기 때문에 추적이 용이하게 됩니다.
답변 감사드립니다!
예를들어 다음과 같은 쿼리가 있을 때
SELECT A.*, B.user_name, C.user_name FROM Company as A JOIN Member as B ON A.founder_id = B.id JOIN Member as C ON A.manager_id = C.id
어떻게 JDSL 로 접근할 수 있을까요?