오늘도 더 나은 코드를 작성하였습니까?

중첩된 관계 정의 본문

Android Jetpack Architecture/Room

중첩된 관계 정의

hik14 2020. 8. 23. 19:59

 서로 관련이 있는 세 개 이상의 테이블 집합을 쿼리 해야 할 수도 있습니다. 이 경우 테이블 간에 중첩된 관계를 정의합니다.

 

음악 스트리밍 앱 예에서 모든 사용자, 각 사용자의 모든 재생목록 및 각 사용자의 각 재생목록에 있는 모든 노래를 쿼리 하려고 한다고 가정해 보겠습니다.

 

사용자는 재생목록과 1 : N 관계가 있으며

재생목록은 노래와 N : N 관계가 있습니다.

 

다음 코드 예에서는 이러한 항목을 나타내는 클래스뿐만 아니라 재생목록과 노래 간의 다대다 관계에 관한 상호 참조 테이블을 보여줍니다.

@Entity
    data class User(
        @PrimaryKey val userId: Long,
        val name: String,
        val age: Int
    )

    @Entity
    data class Playlist(
        @PrimaryKey val playlistId: Long,
        val userCreatorId: Long,
        val playlistName: String
    )

    @Entity
    data class Song(
        @PrimaryKey val songId: Long,
        val songName: String,
        val artist: String
    )

    @Entity(primaryKeys = ["playlistId", "songId"])
    data class PlaylistSongCrossRef(
        val playlistId: Long,
        val songId: Long
    )

먼저 데이터 클래스 및 @Relation 주석을 사용하여 평소처럼 집합 내 두 테이블 간의 관계를 모델링합니다. 다음 예는 Playlist 항목 클래스와 Song 항목 클래스 간의 다대다 관계를 모델링하는 PlaylistWithSongs 클래스를 보여줍니다.

 

data class PlaylistWithSongs(
        @Embedded val playlist: Playlist,
        @Relation(
             parentColumn = "playlistId",
             entityColumn = "songId",
             associateBy = @Junction(PlaylistSongCrossRef::class)
        )
        val songs: List<Song>
    )

이 관계를 나타내는 데이터 클래스를 정의한 후 집합의 다른 테이블과 첫 번째 관계 클래스 간의 관계를 모델링하여 새 관계 내에서 기존 관계를 '중첩'하는 또 다른 데이터 클래스를 만듭니다. 다음 예는 User 항목 클래스와 PlaylistWithSongs 관계 클래스 간의 일대다 관계를 모델링하는 UserWithPlaylistsAndSongs 클래스를 보여줍니다.

 

data class UserWithPlaylistsAndSongs {
        @Embedded val user: User
        @Relation(
            entity = Playlist::class,
            parentColumn = "userId",
            entityColumn = "userCreatorId"
        )
        val playlists: List<PlaylistWithSongs>
    }

각 테이블 간의 관계를 모델링하는 클래스 및 이전의 모든 테이블 간의 관계를 모델링하는 관계 클래스를 만듭니다.

이렇게 하면 쿼리하려는 모든 테이블 간에 중첩된 관계 체인이 생성됩니다.

 

DAO 클래스에 메서드를 추가하여 앱에 필요한 쿼리 기능을 노출합니다. 이 메서드를 사용하려면 Room에서 여러 쿼리를 실행해야 하므로 @Transaction 주석을 추가하여 전체 작업이 원자적으로 실행되도록 해야 합니다.

    @Transaction
    @Query("SELECT * FROM User")
    fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>   

 

중첩된 관계가 있는 데이터를 쿼리 하려면 Room에서 많은 양의 데이터를 조작해야 하며 이는 성능에 영향을 줄 수 있습니다. 따라서 쿼리에서 중첩된 관계를 최대한 적게 사용하세요.

'Android Jetpack Architecture > Room' 카테고리의 다른 글

DAO를 사용하여 데이터 액세스  (0) 2020.08.25
뷰 만들기  (0) 2020.08.24
객체 간 관계 정의  (0) 2020.08.23
테이블 검색 지원  (0) 2020.08.23
Entity 생성하기  (0) 2020.08.23