line / kotlin-jdsl

Kotlin library that makes it easy to build and execute queries without generated metamodel
https://kotlin-jdsl.gitbook.io/docs/
Apache License 2.0
686 stars 85 forks source link

nested column 지원이 안 되는데여..? (사용법 질문) #112

Closed stella6767 closed 1 year ago

stella6767 commented 1 year ago

스크린샷 2022-09-27 오전 10 58 40

https://github.com/line/kotlin-jdsl/issues/79

    val sql:String =     """
            select
                s
            from
                Song s
            left join fetch s.album

            where
                s.id not in (
                    select
                        ps.song.id
                    from
                      PlaylistSong ps                     
                    where
                        ps.playlist.id=$playlistId
                )                                    
                order by s.id desc 
        """.trimIndent()

요런 식의 JPQL을 JDSL 로 바꾸고 싶은데..

        val songs = queryFactory.listQuery<Song> {
            select(entity(Song::class))
            from(entity(Song::class))
            fetch(Song::album, JoinType.LEFT)
            where(column(Song::id).`in`(playlistSongIdss))
        }
  1. JDSL 서브쿼리 쓸 때, fetch 구문은 못 쓰는거죠?
        val playlistSongIdss = queryFactory.subquery<Long> {
            select(column(Song::id))
            from(PlaylistSong::class)
            // fetch     //fetch 구문은 안 되는 듯.

            where(column(PlaylistSong::id).notEqual(playlistId))
        }
  1. nestedCol spec 도 없더라구요. 아직 release 을 안 한 건가요?
val playlistSongIdss = queryFactory.subquery<Long> {
            //select(nestedCol(col(PlaylistSong::song), Song::id)) 
            from(PlaylistSong::class)
            // fetch fetch 구문은 안 되는 듯.
            where(column(PlaylistSong::id).notEqual(playlistId))
        }

지금 현재 build.gradle

    implementation("com.linecorp.kotlin-jdsl:spring-data-kotlin-jdsl-starter:2.0.5.RELEASE")

지금 상태로 저의 구문을 적절하게 Kotlin jdsl로 옮긴다면 어떤형태로 옮겨야될까요. 설명이나 예시가 너무 부족해서 쓰기가 힘듭니다..

shouwn commented 1 year ago

@stella6767 안녕하세요.

  1. JDSL 서브쿼리에서 fetch 사용 가능 여부 네 맞습니다. fetch는 사용할 수 없어서 Subquery DSL 인터페이스에서 제거 되어 있습니다.

  2. nested column 사용 가능 여부 nested column은 2.0.6.RELEASE에 적용 될 예정이며 오늘 배포 예정되어 있습니다. 2.0.6.RELEASE로 버전을 올려주시면 사용이 가능합니다.

  3. JDSL 변환 방법 작성해주신 쿼리의 Entity 구조는 잘 모르지만 아래와 같이 작성했을 때는 원하시는 쿼리가 나온 것을 확인했습니다.

@Entity @Table(name = "test_playlist") data class Playlist( @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long,

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

)

@Entity @Table(name = "test_playlist_song") data class PlaylistSong( @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long,

@ManyToOne
@JoinColumn(name = "playlist_id")
val playlist: Playlist,

@ManyToOne
@JoinColumn(name = "song_id")
val song: Song,

)

@Entity @Table(name = "test_song") data class Song( @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long,

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

@ManyToOne
@JoinColumn(name = "album_id")
val album: Album,

)

@Entity @Table(name = "test_album") data class Album( @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long,

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

)

val subquery = queryFactory.subquery { select(nestedCol(col(PlaylistSong::song), Song::id)) from(entity(PlaylistSong::class)) where(nestedCol(col(PlaylistSong::playlist), Playlist::id).equal(playlist2.id)) }

val songs = queryFactory.listQuery { select(entity(Song::class)) from(entity(Song::class)) fetch(Song::album, JoinType.LEFT) where(not(col(Song::id).in(subquery))) }


쿼리 실행 결과
```sql
select
    song0_.id as id1_13_0_,
    album1_.id as id1_3_1_,
    song0_.album_id as album_id3_13_0_,
    song0_.name as name2_13_0_,
    album1_.name as name2_3_1_ 
from test_song song0_ 
left outer join test_album album1_ on song0_.album_id=album1_.id 
where song0_.id not in  (
    select playlistso2_.song_id 
    from test_playlist_song playlistso2_ 
    where playlistso2_.playlist_id=2
)
  1. 문서화의 빈약함 문서가 빈약하다는 것은 저희도 느끼고 있습니다. 아쉽지만 JDSL에 대한 문서화 및 추가 기능 개발에 사용할 수 있는 개발 리소스가 없어 현재 진척이 없는 상황입니다. 추후 문서화에 사용할 리소스가 확보되면 기쁜 마음으로 다시 말씀드리겠습니다.
shouwn commented 1 year ago

이제 2.0.6.RELEASE가 배포 되어서 nestedCol을 사용하실 수 있습니다.

stella6767 commented 1 year ago

친절한 답변 감사합니다!!