[译] 定义 Realm 对象模式 - Android SDK

原文:https://docs.mongodb.com/realm/sdk/android/examples/define-a-realm-object-model

定义一个 Realm 对象

要在您的应用程序中定义 Realm 对象,请创建 RealmObject 的子类或实现RealmModel。

所有 Realm 对象都必须提供一个空的构造函数。

继承 RealmObject

例子
以下代码块展示了一个描述 Frog 的 Realm 对象。这个 Frog 类可以存储在 Realm 数据库中,因为它继承了 RealmObject 类。

import io.realm.RealmObject

// providing default values for each constructor parameter
// fulfills the need for an empty constructor
open class Frog(
    var name: String? = null,
    var age: Int = 0,
    var species: String? = null,
    var owner: String? = null
) : RealmObject() // To add an object to your Realm Schema, extend RealmObject

所有定义的 Realm 对象都必须使用 open 可见性修饰符。

实现 RealmModel

例子
以下代码块展示了一个描述青蛙的 Realm 对象。这个 Frog 类可以存储在 Realm 数据库中,因为它 实现了 RealmModel 类并且使用了@RealmClass 注解:

import io.realm.RealmModel
import io.realm.annotations.RealmClass

@RealmClass
open class Frog : RealmModel {
    var name: String? = null
    var age = 0
    var species: String? = null
    var owner: String? = 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
}

所有 Realm 对象都必须使用 open 可见性修饰符。

使用 RealmObject 方法

当您通过继承 RealmObject 类创建 Realm 对象时,您可以在 Realm 对象的实例上动态访问 RealmObject 类方法。通过实现 RealmModel 创建的 Realm 对象可以通过RealmObject 类静态访问这些相同的方法:

// With RealmObject
frogRealmObject?.isValid
frogRealmObject?.addChangeListener(listener)

// With RealmModel
RealmObject.isValid(frogRealmModel)
RealmObject.addChangeListener(frogRealmModel, listener)

Lists 列表

Realm 对象可以包含非 Realm 对象数据类型的列表:

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 favoriteColors : RealmList<String>? = null

    constructor(
        name: String?,
        age: Int,
        species: String?,
        owner: String?,
        favoriteColors: RealmList<String>?
    ) {
        this.name = name
        this.age = age
        this.species = species
        this.owner = owner
        this.favoriteColors = favoriteColors
    }

    constructor() {} // RealmObject subclasses must provide an empty constructor
}

定义关系字段

多对一

要设置多对一或一对一关系,请在应用程序中创建一个类型为 Realm 对象的字段:

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
}

每个 Frog 都引用零个 Frog 实例或一个其他 Frog 实例。没有什么可以阻止多个 Frog 实例引用同一个 Frog 实例作为最好的朋友;多对一和一对一关系之间的区别取决于您的应用程序。

多对多

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
}

RealmLists 是 RealmObject 的容器,但其他方面的行为就像一个常规集合。您可以在多个 RealmLists 中使用同一个对象 。

逆关系

默认情况下, Realm 数据库关系是单向的。您可以沿着链接从一个类到一个引用类,但不能沿着相反的方向。考虑以下定义一个有 frogFriends 列表的 Toada 类 :

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() {}
}

您可以提供相反方向的链接,从 Frog 到Toad, 在 final(Java 中)或 val(Kotlin 中)的 RealmResults<T> 类型字段上带有 @LinkingObjects 注解:

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
    @LinkingObjects("frogFriends")
    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 / val。

定义嵌入对象字段

Realm 数据库提供了在其他对象中嵌套对象的能力。这有几个优点:

  • 如果使用 Realm Sync,对象将转换为遵循非规范化数据模型的 MongoDB 文档。
  • 当您删除包含另一个对象的对象时,删除操作会将两个对象从 Realm 中删除,因此未使用的对象不会累积在您的 Realm 文件中,从而占用用户移动设备上的宝贵空间。

要嵌入对象,请在您想要嵌套在另一个类中的类的 @RealmClass 注释中将 embedded 属性设置 true :

import io.realm.RealmObject
import io.realm.annotations.RealmClass

@RealmClass(embedded = true)
open class Fly : RealmObject {
    private var name: String? = null

    constructor(name: String?) {
        this.name = name
    }

    constructor() {} // RealmObject subclasses must provide an empty constructor
}

然后,每当您从另一个类引用该类时,Realm 数据库都会将引用的类嵌入到封闭类中,如下例所示:

import io.realm.RealmObject

open class Frog : RealmObject {
    var name: String? = null
    var age = 0
    var species: String? = null
    var owner: String? = null
    var lastMeal: Fly? = null

    constructor(
        name: String?,
        age: Int,
        species: String?,
        owner: String?,
        lastMeal: Fly?
    ) {
        this.name = name
        this.age = age
        this.species = species
        this.owner = owner
        this.lastMeal = lastMeal
    }

    constructor() {} // RealmObject subclasses must provide an empty constructor
}

Annotations 注解

使用注解来自定义你的 Realm 对象模型。

Primary Key 主键

您可以选择性地通过 @PrimaryKey 注解为一个对象类型定义一个主键,来作为对象模式的一部分:

import io.realm.RealmObject
import io.realm.annotations.PrimaryKey

open class Frog : RealmObject {
    @PrimaryKey var name : String? = null
    var age = 0
    var species: String? = null
    var owner: String? = 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
}

RealmObject 中只有一个字段可以使用 @PrimaryKey 注解。

Required Fields 必需字段

import io.realm.RealmObject
import io.realm.annotations.Required

open class Frog : RealmObject {
    @Required var name: String? = null
    var age = 0
    var species: String? = null
    var owner: String? = 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
}

Optional Fields 可选字段

字段只有在它们可以保存值 null 并且没有用 Required 注解标记时才是可选的。

Default Field Values 字段默认值

要为字段分配默认值,请使用内置语言功能分配默认值。

科特林
爪哇
在字段声明中分配默认值:

import io.realm.RealmObject

open class Frog : RealmObject {
    var name = "Kitty"
    var age = 0
    var species: String? = null
    var owner: String? = 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
}

默认值和可空性
虽然默认值确保新创建的对象不能包含值 null(除非您指定默认值 null),但它们不会影响字段的可空性。要使字段不可为空,请参阅必需字段。

Index a Field 索引一个字段

要索引字段,请使用 @Index 注解:

import io.realm.RealmObject
import io.realm.annotations.Index

open class Frog : RealmObject {
    var name: String? = null
    var age = 0
    @Index var species : String? = null
    var owner: String? = 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
}

Ignore a Field 忽略字段

如果不想将模型中的字段保存到 Realm,则可以忽略字段。

使用 @Ignore 注解忽略 Realm 对象模型中的字段:

import io.realm.RealmObject
import io.realm.annotations.Ignore

open class Frog : RealmObject {
    var name: String? = null
    var age = 0
    var species: String? = null
    // can you ever really own a frog persistently?
    @Ignore var owner  : String? = 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
}

忽略 static 和 transient 字段
标记为 static 或 transient 的字段总是被忽略,不需要 @Ignore 注解。

Rename a Field 重命名字段

默认情况下,Realm 数据库使用模型类中定义的名称在内部表示字段。在某些情况下,您可能希望更改此行为:

  • 为了更轻松地跨平台工作,因为命名约定不同。
  • 在 Kotlin 中更改字段名称而不强制迁移。

选择与模型类中使用的名称不同的内部名称具有以下含义:

  • 创建类和字段时,迁移必须使用内部名称。
  • 模式错误报告将使用内部名称。

使用 @RealmField 注解重命名字段:

import io.realm.RealmObject
import io.realm.annotations.RealmField

open class Frog : RealmObject {
    var name: String? = null
    var age = 0
    @RealmField("latinName") var species: String? = null
    var owner: String? = 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
}

或者,您还可以在模块或类级别分配命名策略,以更改 Realm 数据库解释字段名称的方式。

您可以在模块级别定义命名策略,这将影响模块中包含的所有类:

import io.realm.annotations.RealmModule
import io.realm.annotations.RealmNamingPolicy

@RealmModule(
    allClasses = true,
    classNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES,
    fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES
)
open class MyModule

您还可以在类级别定义命名策略,它会覆盖模块级别的设置:

import io.realm.RealmObject
import io.realm.annotations.RealmClass
import io.realm.annotations.RealmNamingPolicy

@RealmClass(fieldNamingPolicy = RealmNamingPolicy.PASCAL_CASE)
open class Frog : RealmObject {
    var name: String? = null
    var age = 0
    var species: String? = null
    var owner: String? = 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
}

Rename a Class 重命名类

默认情况下,Realm 数据库使用模型类中定义的名称在内部表示类。在某些情况下,您可能希望更改此行为:

  • 在不同的包中支持多个具有相同简单名称的模型类。
  • 为了更轻松地跨平台工作,因为命名约定不同。
  • 使用比 Realm 数据库强制执行的 57 个字符限制更长的类名。
  • 在 Kotlin 中更改类名而不强制迁移。

使用 @RealmClass 注解重命名一个类:

import io.realm.RealmObject
import io.realm.annotations.RealmClass

@RealmClass(name = "Short_Bodied_Tailless_Amphibian")
open class Frog : RealmObject {
    var name: String? = null
    var age = 0
    var species: String? = null
    var owner: String? = 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
}

从你的 Realm 模式中省略类

默认情况下,您的应用程序的 Realm 模式包括所有继承了 RealmObject 的类。如果您只想包含在您的 Realm 模式中继承了 RealmObject 类的子集,您可以在模块中包含该类的子集并使用该模块打开您的 Realm:

import io.realm.annotations.RealmModule

@RealmModule(classes = [Frog::class, Fly::class])
open class MyModule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值