관계 - Java SDK
관계
Realm 을 사용하면 앱의 객체 유형 간의 명시적인 관계를 정의할 수 있습니다. 관계 는 기본 데이터 유형 중 하나가 아닌 다른 Realm 객체 를 참조하는 객체 속성 입니다. 속성 스키마에서 객체 속성 의 유형을 다른 객체 유형으로 설정하여 관계를 정의합니다.
관계는 영역의 다른 객체를 직접 참조하는 것입니다. 즉, 관계형 데이터베이스에서처럼 관계를 정의하기 위해 브리지 테이블이나 명시적 조인이 필요하지 않습니다. 대신 관계를 정의하는 속성을 읽고 작성하여 관련 객체에 액세스할 수 있습니다. Realm은 읽기 작업이 들어오는 대로 느리게 실행되므로 관계를 쿼리하는 것은 일반 속성을 읽는 것과 마찬가지로 성능이 뛰어납니다.
객체 간 관계에는 다음 세 가지 주요 유형이 있습니다.
다음 유형을 사용하여 Realm 객체 스키마에 관계, 컬렉션 및 내장된 객체를 정의할 수 있습니다.
RealmObject
RealmList <? extends RealmObject>
주석을 사용하여 지정된 필드 가 외래 키 관계 를 나타내는지 아니면 내장된 객체 관계 를 나타내는지 나타냅니다. 자세한 내용은 관계 주석을 참조하세요.
일대일 관계
대일 관계는 객체가 특정 방식으로 하나 이상의 다른 객체와 관련되지 않음을 의미합니다. 유형이 관련 Realm 객체 유형인 속성을 지정하여 객체 스키마에서 객체 유형에 대한 대일 관계를 정의합니다.
관계 필드를 null로 설정하면 객체 간의 연결이 제거되지만 Realm은 참조된 객체가 포함되어 있지 않는 한 참조된 객체를 삭제하지 않습니다.
To-Many 관계
대다 관계는 객체가 특정 방식으로 여러 객체와 관련되어 있음을 의미합니다. RealmList<T>
유형의 필드를 사용하여 하나의 객체와 여러 객체 간의 관계를 만들 수 있습니다. 여기서 T
은(는) 애플리케이션의 Realm 객체입니다.
역관계
역 관계는 정의된 대일 또는 대다 관계에서 해당 객체를 참조하는 다른 모든 객체에 객체를 다시 연결합니다. 관계 정의는 단방향이므로 객체 모델의 속성을 역관계로 명시적으로 정의해야 합니다.
예를 들어 '사용자에게 작업이 많이 있음'이라는 대다 관계는 '작업은 사용자에 속함'이라는 역관계를 자동으로 생성하지 않습니다. 객체 모델에서 역관계를 지정하지 않는 경우 지정된 작업에 할당된 사용자를 조회하기 위해 별도의 쿼리를 실행해야 합니다.
역관계를 정의하려면 객체 모델에서 LinkingObjects
속성을 정의합니다. LinkingObjects
정의는 역관계의 객체 유형과 속성 이름을 지정합니다.
Realm은 지정된 관계에서 객체가 추가되거나 제거될 때마다 암시적 관계를 자동으로 업데이트합니다. 역관계 속성의 값은 수동으로 설정할 수 없습니다.
@LinkingObjects
주석이 달린 필드는 다음과 같아야 합니다.
표시
final
RealmResults<T>
유형이어야 합니다. 여기서T
은(는) 관계의 반대쪽 끝에 있는 유형입니다.
관계는 다대일 또는 다대다이므로 역관계를 따르는 경우 객체가 0개, 1개 또는 여러 개일 수 있습니다.
다른 RealmResults
세트와 마찬가지로 역관계를 쿼리할 수 있습니다.
관계 필드 정의
경고
수정 가능한 필드에 항상 접근자와 변경자를 정의하세요.
영역 객체는 게터 및 세터를 사용하여 업데이트된 필드 값을 영역에 유지합니다. 업데이트에는 항상 게터와 세터를 사용하세요.
다대일
다대일 또는 일대일 관계를 설정하려면 애플리케이션에서 Realm 객체 유형의 필드를 생성하세요.
import io.realm.RealmObject; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private Frog bestFriend; public Frog(String name, int age, String species, String owner, Frog bestFriend) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.bestFriend = bestFriend; } public Frog(){} // RealmObject subclasses must provide an empty constructor public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } public Frog getBestFriend() { return bestFriend; } public void setBestFriend(Frog bestFriend) { this.bestFriend = bestFriend; } }
import io.realm.RealmObject open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null var bestFriend: Frog? = null constructor( name: String?, age: Int, species: String?, owner: String?, bestFriend: Frog? ) { this.name = name this.age = age this.species = species this.owner = owner this.bestFriend = bestFriend } constructor() {} // RealmObject subclasses must provide an empty constructor }
중요
대일 관계는 선택 사항이어야 합니다.
객체 모델에서 대일 관계를 선언할 때는 선택적 속성이어야 합니다. 대일 관계를 필수로 만들려고 하면 Realm은 런타임에 예외를 발생시킵니다.
각 Frog
은(는) 0개의 Frog
인스턴스 또는 다른 Frog
인스턴스를 참조합니다. 여러 Frog
인스턴스가 동일한 Frog
을(를)가장 친한 친구로 참조하는 것을 방지하는 방법은 없습니다. 다대일 관계와 일대일 관계의 차이는 애플리케이션에 따라 다릅니다.
Many-to-Many
import io.realm.RealmList; import io.realm.RealmObject; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private RealmList<Frog> bestFriends; public Frog(String name, int age, String species, String owner, RealmList<Frog> bestFriends) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.bestFriends = bestFriends; } public Frog(){} // RealmObject subclasses must provide an empty constructor public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } public RealmList<Frog> getBestFriends() { return bestFriends; } public void setBestFriends(RealmList<Frog> bestFriends) { this.bestFriends = bestFriends; } }
import io.realm.RealmList import io.realm.RealmObject open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null var bestFriends: RealmList<Frog>? = null constructor( name: String?, age: Int, species: String?, owner: String?, bestFriends: RealmList<Frog>? ) { this.name = name this.age = age this.species = species this.owner = owner this.bestFriends = bestFriends } constructor() {} // RealmObject subclasses must provide an empty constructor }
RealmList
s는 RealmObject
의 컨테이너이지만 그 외에는 일반 컨테이너처럼 작동합니다. 여러 RealmList
에서 동일한 객체를 사용할 수 있습니다.
역관계
기본적으로 Realm 관계는 단방향입니다. 한 클래스에서 참조된 클래스로 연결되는 링크를 따라갈 수 있지만 반대 방향으로는 갈 수 없습니다. frogFriends
목록으로 Toad
을(를) 정의하는 다음 클래스를 고려해 보세요.
import io.realm.RealmList; import io.realm.RealmObject; public class Toad extends RealmObject { private RealmList<Frog> frogFriends; public Toad(RealmList<Frog> frogFriends) { this.frogFriends = frogFriends; } public Toad() {} public RealmList<Frog> getFrogFriends() { return frogFriends; } public void setFrogFriends(RealmList<Frog> frogFriends) { this.frogFriends = frogFriends; } }
import io.realm.RealmList import io.realm.RealmObject open class Toad : RealmObject { var frogFriends: RealmList<Frog>? = null constructor(frogFriends: RealmList<Frog>?) { this.frogFriends = frogFriends } constructor() {} }
RealmResults<T>
유형의 final
(Java의 경우) 또는 val
(Kotlin의 경우) 필드에 @LinkingObjects 주석을 사용하여 Frog
에서 Toad
로 반대 방향으로 링크를 제공할 수 있습니다.
import io.realm.RealmObject; import io.realm.RealmResults; import io.realm.annotations.LinkingObjects; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private final RealmResults<Toad> toadFriends = null; public Frog(String name, int age, String species, String owner) { this.name = name; this.age = age; this.species = species; this.owner = owner; } public Frog(){} // RealmObject subclasses must provide an empty constructor public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } }
import io.realm.RealmObject import io.realm.RealmResults import io.realm.annotations.LinkingObjects open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null private val toadFriends: RealmResults<Toad>? = null constructor(name: String?, age: Int, species: String?, owner: String?) { this.name = name this.age = age this.species = species this.owner = owner } constructor() {} // RealmObject subclasses must provide an empty constructor }
중요
역관계 필드는 final
(으)로 표시해야 합니다.