일대일 관계 정의 및 쿼리

두 항목 간의 일대일 관계 는 상위 항목의 각 인스턴스가 정확히 하나의 하위 항목 인스턴스에 상응하는 관계이며, 그 반대의 경우도 마찬가지입니다.

예를 들어 사용자가 소유한 노래 라이브러리가 있는 음악 스트리밍 앱을 생각해 보세요. 사용자마다 라이브러리가 한 개만 있고 각 라이브러리는 정확히 한 명의 사용자에 상응합니다. 따라서 User 항목과 Library 항목은 일대일 관계입니다.

다음 단계에 따라 데이터베이스에서 일대일 관계를 정의하고 쿼리하세요.

  1. 관계 정의: 두 항목의 클래스를 만들고 하나가 다른 항목의 기본 키를 참조하는지 확인합니다.
  2. 항목 쿼리: 새 데이터 클래스에서 관계를 모델링하고 관련 데이터를 가져오는 함수를 만듭니다.

관계 정의

일대일 관계를 정의하려면 먼저 두 항목 각각의 클래스를 만듭니다. 항목 중 하나는 다른 항목의 기본 키를 참조하는 변수를 포함해야 합니다.

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

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userOwnerId: Long
)

항목 쿼리

사용자 및 상응하는 라이브러리의 목록을 쿼리하려면 먼저, 두 항목 간의 일대일 관계를 모델링해야 합니다.

관계를 모델링하려면 각 인스턴스가 상위 항목 인스턴스 및 상응하는 하위 항목을 보유하는 새 데이터 클래스를 만듭니다. 하위 항목에 @Relation 주석을 추가합니다. parentColumns를 상위 항목의 기본 키 열 이름으로 설정하고 entityColumns를 상위 항목의 기본 키를 참조하는 하위 항목의 열 이름으로 설정합니다.

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userOwnerId"]
    )
    val library: Library
)

마지막으로, 상위 항목과 하위 항목을 쌍으로 하는 데이터 클래스의 모든 인스턴스를 반환하는 함수를 데이터 액세스 객체 (DAO) 클래스에 추가합니다. 이 함수를 사용하려면 Room에서 두 개의 쿼리를 실행해야 하므로 @Transaction 주석을 추가하여 Room에서 전체 작업을 원자적으로 실행하도록 합니다.

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersAndLibraries(): List<UserAndLibrary>

복합 키

복합 키를 사용하여 관계를 정의하는 경우 parentColumnsentityColumns에 여러 열을 지정합니다. parentColumns의 열 순서는 entityColumns의 열 순서와 일치해야 합니다.

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String,
    val lastName: String,
    val age: Int
)

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userFirstName: String,
    val userLastName: String
)

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val library: Library
)