관계 - Kotlin SDK
이 페이지에서는 데이터 모델 에서 객체 간의 관계를 정의하는 방법을 설명합니다. Realm 객체와 이를 정의하는 방법을 학습 보려면 Realm Realm 객체 모델 정의 - 코틀린 SDK (Kotlin SDK) 를 참조하세요.
관계형 데이터베이스와 달리 Realm은 브리지 테이블이나 명시적 조인을 사용하여 관계를 정의하지 않습니다. 대신 Realm은 포함된 객체 또는 다른 Realm 객체에 대한 참조 속성을 통해 관계를 처리합니다. 이러한 속성에서 직접 읽고 쓸 수 있습니다. 이렇게 하면 다른 속성에 대해 쿼리하는 것처럼 관계 쿼리 성능이 향상됩니다.
관계 유형
Realm 객체 간의 관계에는 두 가지 주요 유형이 있습니다.
일대일 관계
To-Many 관계
Realm 은 본질적으로 동일한 영역 내의 다른 객체로부터의 객체 참조를 제한 하지 않습니다 . 이는 Realm 관계가 암시적으로 '다대일' 또는 '다대다'임을 의미합니다. 관계 를 "다대일/다대다" 대신 "일대일/일대다"로 제한하는 유일한 방법은 내장된 객체 를 사용하는 객체 입니다.
관계 정의
다른 Realm 객체를 참조하는 객체 속성을 정의하여 객체 스키마에서 관계를 정의할 수 있습니다. Realm 객체를 속성으로 사용하는 방법에 대해 자세히 알아보세요.
다음 유형을 사용하여 관계를 정의할 수 있습니다.
RealmObject
RealmList <? extends RealmObject>
RealmSet <? extends RealmObject>
한 Realm 객체를 다른 Realm 객체 내에 직접 포함하여 EmbeddedRealmObject
유형의 중첩 데이터 구조를 만들 수도 있습니다. 그러나 포함된 객체에는 추가 제약 조건이 있습니다. 자세한 내용은 내장된 객체 정의 섹션을 참조하세요.
대일 관계 속성 정의
관계 관계 는 하나의 속성 을 RealmObject
객체 유형의 단일 인스턴스 에 매핑합니다. 여러 상위 객체 인스턴스가 동일한 하위 인스턴스 를 참조하는 것을 방지하는 것은 없습니다. 엄격한 일대일 관계 를 시행하다 하려면 내장된 객체 를 대신 사용하세요.
참고
대일 관계 필드 를 null
로 설정하면 객체 간의 연결이 제거되지만 Realm 은 참조된 객체 를 삭제 하지 않습니다. 상위 객체 가 삭제될 때 참조된 객체 를 삭제 하려면 내장된 객체 를 대신 사용합니다.
객체 간의 대일 관계를 정의하려면 데이터 모델에 정의된 RealmObject
객체 유형의 선택적 객체 속성을 정의합니다. 이는 다른 Realm 객체 유형일 수도 있고 동일한 Realm 객체 유형일 수도 있습니다.
// Relationships of Realm objects must be of RealmObject type class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int = 0 // Property of RealmObject type (MUST be null) var favoritePond: Pond? = null var bestFriend: Frog? = null }
대다 관계 속성 정의
대다 관계 는 하나의 속성을 0개 이상의 RealmObject
객체 유형 인스턴스에 매핑합니다. 여러 상위 객체 인스턴스가 동일한 하위 인스턴스를 참조하는 것을 방지하는 것은 없습니다. 엄격한 일대다 관계를 적용하려면 포함된 객체를 대신 사용하세요.
Realm 에서 대다 관계는 Realm 객체의 컬렉션( RealmList 또는 RealmSet)입니다. 객체 모델 에서 컬렉션을 정의하는 방법에 대한 자세한 내용은 컬렉션 속성 정의를 참조하세요.
객체 간의 대다 관계 를 정의하려면 유형이 RealmList<E>
또는 RealmSet<E>
인 객체 속성 을 정의하고, 여기서 <E>
는 데이터 모델 에 정의된 RealmObject
객체 유형입니다. 이는 다른 Realm 객체 유형 수도 있고 동일한 Realm 객체 유형 수도 있습니다.
// Relationships of RealmList<E> or RealmSet<E> must be of RealmObject type class Forest : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Set of RealmObject type (CANNOT be null) var frogsThatLiveHere: RealmSet<Frog> = realmSetOf() // List of RealmObject type (CANNOT be null) var nearbyPonds: RealmList<Pond> = realmListOf() }
역관계 정의
역관계 는 하위 RealmObject
객체와 이를 참조하는 다른 상위 객체 간의 자동 역 링크 관계입니다. 역관계는 다대일 또는 다대다 관계의 하위 객체에 다시 연결할 수 있습니다. 엄격한 일대일 또는 일대다 역관계를 적용하려면 포함된 객체를 대신 사용하세요.
관계 정의는 단방향이므로 객체 모델의 속성 을 관계 로 명시적으로 정의해야 합니다. 예를 예시'사용자에게 많은 게시물이 있음'이라는 대다 관계 는 '게시물이 사용자에게 속함'이라는 관계 자동으로 생성하지 않습니다. 그러나 게시물의 소유자를 가리키는 사용자 속성 을 게시물에 추가할 수 있습니다. 이를 통해 게시 이 속한 사용자를 조회하기 위해 별도의 쿼리 를 실행 하는 대신 게시 과 사용자 관계 를 쿼리 할 수 있습니다. 관계는 다대일 또는 다대다이므로 역관계를 따르면 객체가 0개, 1개 또는 여러 개일 수 있습니다.
참고
Realm은 지정된 관계에서 객체가 추가되거나 제거될 때마다 암시적 관계를 자동으로 업데이트합니다. 역링크 컬렉션에서 항목을 수동으로 추가하거나 제거할 수 없습니다.
객체 간의 역관계를 정의하려면 먼저 유형이 RealmList<E>
, RealmSet<E>
또는 RealmDictionary<E>
인 상위 객체에서 컬렉션 속성을 정의하며, 여기서 <E>
은 데이터 모델에 정의된 RealmObject
객체 유형입니다. . 이는 다른 Realm 객체 유형일 수도 있고 동일한 Realm 객체 유형일 수도 있습니다.
// Parent object must have RealmList<E>, RealmSet<E>, or // RealmDictionary<K,V> property of child type class User : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of child RealmObject type (CANNOT be nullable) var posts: RealmList<Post> = realmListOf() // Set of child RealmObject type (CANNOT be nullable) var favoritePosts: RealmSet<Post> = realmSetOf() // Dictionary of child RealmObject type (value MUST be nullable) var postByYear: RealmDictionary<Post?> = realmDictionaryOf() }
그런 다음 RealmResults<E>
의 하위 객체에 불변의 역 링크 속성을 정의하고, 여기서 <E>
는 상위 객체 유형입니다.
// Backlink of RealmObject must be RealmResults<E> of parent object type class Post : RealmObject { var title: String = "" var date: RealmInstant = RealmInstant.now() // Backlink to parent RealmObject type (CANNOT be null & MUST be val) val user: RealmResults<User> by backlinks(User::posts) }
포함된 객체 정의
내장된 객체 는 단일 특정 상위 객체 내에 데이터를 중첩하는 데 사용할 수 있는 특수한 유형의 Realm 객체 입니다. 포함된 객체는 이전 섹션에서 설명한 관계 와 유사한 일대일, 일대다 또는 관계 일 수 있지만, 단일 상위 객체 관계 EmbeddedRealmObject
유형.
포함된 객체는 독립적인 Realm 객체로 존재할 수 없으므로 고려해야 할 추가 제약 조건이 있습니다.
포함된 객체는 상위 객체가 엄격한 소유권을 갖습니다. 상위 객체 간에 포함된 객체를 공유할 수 없습니다.
내장된 객체 는 상위 객체의 라이프사이클을 상속합니다. 예를 예시, 상위 객체 를 삭제하면 내장된 객체 도 삭제됩니다.
포함된 객체는 명확한 포함 관계 또는 소유권 관계 가 있을 때 유용합니다. 예를 예시 Address
객체 는 사용자 컨텍스트 내의 애플리케이션 에서만 의미가 있기 때문에 User
객체 에 포함될 수 있습니다.
팁
재사용 및 구성 가능한 내장된 객체 유형
여러 상위 객체 유형과 다른 내장된 객체 유형 내에서 동일한 내장된 객체 유형을 사용할 수 있습니다.
일대일 관계
상위 항목과 일대일 관계로 포함된 객체를 정의하려면 데이터 모델에 이미 정의된 EmbeddedRealmObject
유형의 객체 속성을 정의합니다.
// To-one embedded relationships must be of EmbeddedRealmObject type class Contact : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Property of EmbeddedRealmObject type (MUST be null) var address: EmbeddedAddress? = null } class EmbeddedAddress : EmbeddedRealmObject { var propertyOwner: Contact? = null var street: String? = "" // Embed another EmbeddedRealmObject type var country: EmbeddedCountry? = null } class EmbeddedCountry : EmbeddedRealmObject { var name: String = "" }
일대다 관계
상위 항목과 일대다 포함 관계가 있는 포함된 객체를 정의하려면 유형이 RealmList<E>
인 객체 속성을 정의하고, 여기서 <E>
은 데이터 모델에 정의된 EmbeddedRealmObject
객체 유형입니다.
// To-many embedded relationships must be a RealmList<E> or // RealmDictionary<K, V> property of EmbeddedRealmObject type class Business : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of EmbeddedRealmObject type (CANNOT be null) var addresses: RealmList<EmbeddedAddress> = realmListOf() // Dictionary of EmbeddedRealmObject type (value MUST be nullable) var addressByYear: RealmDictionary<EmbeddedAddress?> = realmDictionaryOf() }
RealmSet<E>
은(는) 포함된 객체를 지원하지 않으므로 RealmSet<E>
유형으로 포함된 객체를 정의 할 수 없습니다 .
역관계
상위 객체와 역관계가 있는 포함된 객체를 정의하려면 먼저 유형이 RealmList<E>
또는 RealmDictionary<E>
인 상위 객체에서 컬렉션 속성을 정의하고, 여기서 <E>
는 데이터 모델에 정의된 EmbeddedRealmObject
객체 유형입니다. :
// Parent object must have RealmList<E> or RealmDictionary<K, V> // property of child EmbeddedRealmObject type class User : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of child EmbeddedRealmObject type (CANNOT be nullable) var posts: RealmList<Post> = realmListOf() // Dictionary of child EmbeddedRealmObject type (value MUST be nullable) var postByYear: RealmDictionary<Post?> = realmDictionaryOf() }
RealmSet<E>
은(는) 포함된 객체를 지원하지 않으므로 RealmSet<E>
유형으로 포함된 객체를 정의 할 수 없습니다 .
그런 다음 유형이 상위 객체 유형인 하위 객체 에서 변경할 수 없는 역링크 속성 을 정의합니다.
// Backlink of EmbeddedRealmObject must be parent object type class Post : EmbeddedRealmObject { var title: String = "" var date: RealmInstant = RealmInstant.now() // Backlink to parent RealmObject type (CANNOT be null & MUST be val) val user: User by backlinks(User::posts) }