Definir um modelo de objeto de domínio - SDK Java
Nesta página
- Definir um objeto de domínio
- Ampliar
RealmObject
- Implementar
RealmModel
- Listas
- Definir um campo de objeto incorporado
- Anotações
- Chave primária
- Campos obrigatórios
- Campos opcionais
- Valores de campo padrão
- Indexar um campo
- Ignorar um campo
- Renomear um campo
- Renomear uma turma
- Omitir classes do seu esquema de domínio
Definir um objeto de domínio
Para definir um Objeto de Realm em seu aplicação, crie uma subclasse de RealmObject ou implemente o RealmModel.
Importante
Todos os objetos do Realm devem fornecer um construtor vazio.
Todos os objetos de Realm devem usar o modificador de visibilidade
public
em Java ou o modificador de visibilidadeopen
em Kotlin.
Observação
Os nomes das classes têm um limite máximo de 57 caracteres UTF-8.
Ampliar RealmObject
O seguinte bloco de código mostra um objeto de Realm que descreve um Frog. Esta classe Frog pode ser armazenada no Realm porque é extends
a classe RealmObject
.
import io.realm.RealmObject; // To add an object to your Realm Schema, extend RealmObject public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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 // 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
Implementar RealmModel
O seguinte bloco de código mostra um objeto de Realm que descreve um Frog. Esta classe de rã pode ser armazenada no Realm porque implements
a classe RealmModel
e utiliza a anotação @RealmClass
:
import io.realm.RealmModel; import io.realm.annotations.RealmClass; public class Frog implements RealmModel { private String name; private int age; private String species; private String owner; 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; } }
Importante
Todos os objetos de Realm devem usar o modificador de visibilidade public
.
import io.realm.RealmModel import io.realm.annotations.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 }
Importante
Todos os objetos de Realm devem usar o modificador de visibilidade open
.
Dica
Usando métodos do RealmObject
Quando você cria um objeto de Realm estendendo a classe RealmObject
, pode acessar os métodos da classe RealmObject
dinamicamente nas instâncias do seu objeto de Realm. Os objetos de realm criados pela implementação do RealmModel
podem acessar esses mesmos métodos estaticamente por meio da classe RealmObject
:
// With RealmObject frogRealmObject.isValid(); frogRealmObject.addChangeListener(listener); // With RealmModel RealmObject.isValid(frogRealmModel); RealmObject.addChangeListener(frogRealmModel, listener);
// With RealmObject frogRealmObject?.isValid frogRealmObject?.addChangeListener(listener) // With RealmModel RealmObject.isValid(frogRealmModel) RealmObject.addChangeListener(frogRealmModel, listener)
Listas
Os objetos de Realm podem conter listas de tipos de dados que não são objetos de Realm:
Ao contrário das listas de objetos de Realm , essas listas podem conter valores nulos. Se valores nulos não devem ser permitidos, use a anotação @Required .
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<String> favoriteColors; public Frog(String name, int age, String species, String owner, RealmList<String> favoriteColors) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.favoriteColors = favoriteColors; } 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<String> getFavoriteColors() { return favoriteColors; } public void setFavoriteColors(RealmList<String> favoriteColors) { this.favoriteColors = favoriteColors; } }
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 }
Definir um campo de objeto incorporado
O Realm fornece a capacidade de aninhar objetos dentro de outros objetos. Isso tem várias vantagens:
Se estiver usando o Sync, os objetos serão convertidos em documentos do MongoDB que seguem um modelo de dados desnormalizado.
Quando você exclui um objeto que contém outro objeto, a operação de exclusão remove ambos os objetos do realm, para que os objetos não utilizados não se acumulem no arquivo do realm, ocupando um espaço valioso nos dispositivos móveis do usuário.
Para incorporar um objeto, defina a propriedade embedded
da anotação @RealmClass como true
na classe que você deseja aninhar em outra classe:
import io.realm.RealmObject; import io.realm.annotations.RealmClass; public class Fly extends RealmObject { private String name; public Fly(String name) { this.name = name; } public Fly() {} // RealmObject subclasses must provide an empty constructor }
import io.realm.RealmObject import io.realm.annotations.RealmClass open class Fly : RealmObject { private var name: String? = null constructor(name: String?) { this.name = name } constructor() {} // RealmObject subclasses must provide an empty constructor }
Em seguida, sempre que você fizer referência a essa classe de outra classe, Realm incorporará a classe referenciada dentro da classe de encerramento, como no exemplo a seguir:
import io.realm.RealmObject; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private Fly lastMeal; public Frog(String name, int age, String species, String owner, Fly lastMeal) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.lastMeal = lastMeal; } 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 Fly getLastMeal() { return lastMeal; } public void setLastMeal(Fly lastMeal) { this.lastMeal = lastMeal; } }
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 }
Anotações
Use anotações para personalizar seus modelos de objeto de Realm.
Chave primária
Novidades na versão 10.6.0: Realm indexa automaticamente campos de chave primária. Anteriormente, o Realm indexava apenas String
chaves primárias automaticamente.
Realm trata campos marcados com a anotação @PrimaryKey como chaves primárias para seu esquema de objeto correspondente. As chaves primárias estão sujeitas às seguintes limitações:
Você pode definir apenas uma chave primária por esquema de objeto.
Os valores de chave primária devem ser únicos em todas as instâncias de um objeto em um domínio. Tentar inserir um valor de chave primária duplicado resulta em uma RealmPrimaryKeyConstraintException.
Os valores de chave primária são imutáveis. Para alterar o valor da chave primária de um objeto, você deve excluir o objeto original e inserir um novo objeto com um valor de chave primária diferente.
Objetos embarcados não podem definir uma chave primária.
Você pode criar uma chave primária com qualquer um dos seguintes tipos:
String
UUID
ObjectId
Integer
ouint
Long
oulong
Short
oushort
Byte
oubyte[]
Tipos não primitivos podem conter um valor de null
como um valor de chave primária, mas apenas para um objeto de um tipo específico, já que cada valor de chave primária deve ser exclusivo. Tentar inserir um objeto com uma chave primária existente em um domínio resultará em uma RealmPrimaryKeyConstraintException.
O Realm indexa automaticamente os campos de chave primária, o que permite que você leia e modifique objetos com eficiência com base em sua chave primária.
Não é possível alterar o campo de chave primária de um tipo de objeto depois de adicionar qualquer objeto desse tipo a um Realm. Se você estiver usando Sync, não poderá alterar o campo de chave primária de um objeto depois de definir a chave primária no esquema de backend .
Objetos incorporados não podem conter chaves primárias.
Opcionalmente, você pode definir uma chave primária para um tipo de objeto como parte do esquema de objeto com a anotação @PrimaryKey:
import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.PrimaryKey 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 }
Campos obrigatórios
import io.realm.RealmObject; import io.realm.annotations.Required; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.Required 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 }
Campos opcionais
Os campos marcados com tipos de objeto Java e tipos anuláveis Kotlin (terminando com ?
) são anuláveis por padrão. Todos os outros tipos (primitivos, tipos de objeto Kotlin não anuláveis) são exigidos por padrão. Você pode marcar um campo anulável com a anotação @Required para impedir que esse campo mantenha um valor nulo. RealmLists nunca são anuláveis, mas você pode usar a anotação @Required
para impedir que objetos em uma lista mantenham um valor nulo, mesmo que o tipo base o permita. Você não pode marcar um RealmList
de RealmObject
subtipos como obrigatório.
Você pode fazer com que qualquer um dos seguintes tipos seja obrigatório:
String
UUID
ObjectId
Integer
Long
Short
Byte
oubyte[]
Boolean
Float
Double
Date
RealmList
Tipos primitivos como int
e o tipo RealmList
são implicitamente exigidos. Os campos com o tipo RealmObject
são sempre anuláveis e não podem ser necessários.
Importante
Tipos de Kotlin e nulidade
Em Kotlin, os tipos não são anuláveis por padrão, a menos que você adicione explicitamente um sufixo ?
ao tipo. Você só pode anotar tipos anuláveis. A utilização da anotação @Required
em tipos não anuláveis falhará na compilação.
Os campos anuláveis são opcionais por padrão no Realm, a menos que especificado de outra forma com a anotação @Required. Os seguintes tipos são anuláveis:
String
Date
UUID
ObjectId
Integer
Long
Short
Byte
oubyte[]
Boolean
Float
Double
Tipos primitivos como int
e long
não são anuláveis por padrão e não podem ser tornados anuláveis, pois não podem ser definidos para um valor nulo.
Em Kotlin, os campos são considerados anuláveis somente se um campo estiver marcado como anulável com o Kotlin? operador exceto para os seguintes tipos:
String
Date
UUID
ObjectId
Decimal128
RealmAny
Você pode exigir qualquer tipo que termine com o operador Kotlin ?
, como Int?
.
O tipo RealmList
não pode ser anulado por padrão e não pode ficar anulável.
Valores de campo padrão
Para atribuir um valor padrão para um campo, utilize as feições de idioma embutidas para atribuir valores padrão.
Use o(s) construtor(es) de classe para atribuir valores padrão:
import io.realm.RealmObject; public class Frog extends RealmObject { private String name = "Kitty"; private int age; private String species; private String owner; 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; } }
Atribuir valores padrão na declaração de campo:
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 }
Observação
Valores padrão e anulabilidade
Embora os valores padrão garantam que um objeto recém-criado não possa conter um valor de null
(a menos que você especifique um valor padrão de null
), eles não afetam a anulabilidade de um campo. Para tornar um campo não anulável, consulte Campos obrigatórios.
Indexar um campo
Os Índices oferecem suporte à execução eficiente de queries no Realm. Sem índices, o Realm deve executar uma varredura de coleção, ou seja, digitalizar todos os documentos de uma coleção, para selecionar os documentos que correspondem a uma query. Se existir um índice apropriado para uma query, o Realm poderá usar o índice para limitar o número de documentos que deve inspecionar.
Os índices são estruturas de dados especiais que armazenam uma pequena parte dos dados de um domínio em um formato fácil de percorrer. O índice armazena o valor de um campo específico ordenado pelo valor do campo. A ordenação das entradas do índice suporta correspondências de igualdade eficientes e operações de query baseadas em intervalo.
Adicionar um índice pode acelerar algumas queries ao custo de tempos de gravação um pouco mais lentos e sobrecarga adicional de armazenamento e memória. Os índices exigem espaço no arquivo de realm, portanto, adicionar um índice a uma propriedade aumentará o espaço em disco consumido pelo arquivo de realm. Toda entrada do índice tem um mínimo de 12 bytes.
Você pode indexar campos com os seguintes tipos:
String
UUID
ObjectId
Integer
ouint
Long
oulong
Short
oushort
Byte
oubyte[]
Boolean
oubool
Date
RealmAny
O Realm cria índices para campos anotados com @Índice.
Para indexar um campo, use a anotação @Índice:
import io.realm.RealmObject; import io.realm.annotations.Index; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.Index 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 }
Ignorar um campo
Se você não deseja salvar um campo em seu modelo em um domínio, você pode ignorar um campo.
Ignorar um campo de um modelo de objeto de Realm com a anotação @Ignorar:
import io.realm.RealmObject; import io.realm.annotations.Ignore; public class Frog extends RealmObject { private String name; private int age; private String species; // can you ever really own a frog persistently? private String owner; 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.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? 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 }
Observação
O SDK ignora campos estáticos e transitórios
Os campos marcados como static
ou transient
são sempre ignorados e não precisam da anotação @Ignore
.
Renomear um campo
Por padrão, o Realm utiliza o nome definido na classe de modelo para representar campos internamente. Em alguns casos, você pode querer alterar este comportamento:
Para facilitar o trabalho em todas as plataformas, uma vez que as convenções de nomenclatura são diferentes.
Para alterar um nome de campo em Kotlin sem forçar uma migração.
Escolher um nome interno diferente do nome usado nas classes de modelo tem as seguintes implicações:
As migrações devem usar o nome interno ao criar classes e campos.
Erros de esquema relatados usarão o nome interno.
Use a anotação @RealmField para renomear um campo:
import io.realm.RealmObject; import io.realm.annotations.RealmField; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.RealmField 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 }
Como alternativa, você também pode atribuir uma política de nomenclatura nos níveis de módulo ou classe para alterar a maneira como o Realm interpreta os nomes de campo.
Você pode definir uma política de nomenclatura no nível do módulo, que afetará todas as classes incluídas no módulo:
import io.realm.annotations.RealmModule; import io.realm.annotations.RealmNamingPolicy; public class MyModule { }
import io.realm.annotations.RealmModule import io.realm.annotations.RealmNamingPolicy open class MyModule
Você também pode definir uma política de nomenclatura no nível da classe, que substitui as configurações de nível de módulo:
import io.realm.RealmObject; import io.realm.annotations.RealmClass; import io.realm.annotations.RealmNamingPolicy; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.RealmClass import io.realm.annotations.RealmNamingPolicy 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 }
Renomear uma turma
Por padrão, o Realm utiliza o nome definido na classe de modelo para representar classes internamente. Em alguns casos, você pode querer alterar esse comportamento:
Para oferecer suporte a várias classes de modelo com o mesmo nome simples em pacotes diferentes.
Para facilitar o trabalho em todas as plataformas, uma vez que as convenções de nomenclatura são diferentes.
Para usar um nome de classe maior que o limite de 57 caracteres imposto pelo Realm.
Para alterar o nome de uma classe em Kotlin sem forçar uma migração.
Use a anotação @RealmClass para renomear uma classe:
import io.realm.RealmObject; import io.realm.annotations.RealmClass; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.RealmClass 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 }
Omitir classes do seu esquema de domínio
Por padrão, o esquema do Realm do seu aplicativo inclui todas as classes que estendem o RealmObject
. Se você quiser incluir apenas um subconjunto de classes que estendam RealmObject
em seu esquema de domínio, você pode incluir esse subconjunto de classes em um módulo e abrir seu domínio usando esse módulo:
import io.realm.annotations.RealmModule; public class MyModule { }
import io.realm.annotations.RealmModule open class MyModule