CRUD – Read – SDK do Flutter
Nesta página
- Leia as características
- Os resultados não são cópias
- Os resultados são preguiçosos
- As referências são retidas
- Limitando resultados da consulta
- Paginação
- Ler objetos
- Encontrar objeto por chave primária
- query todos os objeto
- query relacionados a objeto
- Listas de query
- Consultar Coleções aninhadas de dados mistos
- Converter listas ou conjuntos em resultados
- Filtrar resultados
- Filtrar com pesquisa por texto completo
- Classificar resultados
- Limitar resultados
Você pode reler os dados armazenados no reconhecimento de data center encontrando, filtrando e ordenando objeto.
Uma leitura do reconhecimento de data center geralmente consiste nas seguintes etapas:
Obtenha todos os objeto de um determinado tipo do reconhecimento de data center.
Opcionalmente, filtre os resultados.
As operações de query retornam uma coleção de . Essas coleções estão ativas, o que significa que elas sempre contêm os resultados mais recentes da consulta associada.
Leia as características
Projete os padrões de acesso a dados da sua aplicação em torno dessas três principais características de leitura para ler os dados da forma mais eficiente possível.
Os resultados não são cópias
Os resultados de uma query não são cópias dos seus dados. A modificação dos resultados de uma query modifica diretamente os dados no disco. Esse mapeamento de memória também significa que os resultados são ao vivo: ou seja, eles sempre refletem o estado atual no disco.
Os resultados são preguiçosos
O SDK só executa uma query quando você realmente solicita os resultados dessa query. Com essa avaliação preguiçosa, você consegue escrever um código de alto desempenho para lidar com grandes conjuntos de dados e query complexas. Você pode encadear várias operações de filtro sem exigir trabalho extra para processar o estado intermediário.
As referências são retidas
Uma vantagem do Realm Object Model do SDK é que o SDK retém automaticamente todos os relacionamento de um objeto como referências diretas. Isso permite que você percorra o gráfico de relacionamento diretamente por meio dos resultados de uma query.
Uma referência direta, ou ponteiro, permite que você acesse diretamente as propriedades de um objeto relacionado por meio da referência.
Outros bancos de dados geralmente copiam objetos do armazenamento do banco de dados para a memória do aplicativo quando você precisa trabalhar com eles diretamente. Como os objetos do aplicativo contêm referências diretas, você tem uma opção: copiar o objeto referido por cada referência direta para fora do banco de dados, caso seja necessário, ou apenas copiar a chave estrangeira de cada objeto e consultar o objeto com essa chave, se ele for acessado. Se você optar por copiar os objetos referenciados para a memória do aplicativo, poderá usar muitos recursos para objetos que nunca são acessados, mas se optar por copiar apenas a chave estrangeira, as pesquisas de objetos referenciados poderão causar lentidão no aplicativo.
O SDK contorna tudo isso com objetos ativos de cópia zero. Os acessadores de objeto do SDK ponto diretamente para o reconhecimento de data center usando o mapeamento de memória, portanto não há distinção entre o objeto no reconhecimento de data center e os resultados da query na memória da aplicação. Por isso você pode percorrer referências diretas em um reconhecimento de data center inteiro a partir de qualquer resultado de query.
Limitando resultados da consulta
Como resultado da avaliação preguiçosa, você não precisa de nenhum mecanismo especial para limitar os resultados da consulta com o SDK. Por exemplo, se a sua query corresponder a milhares de objeto, mas você quiser carregar somente os dez primeiros, basta acessar somente os dez primeiros elementos da collection de resultados.
Paginação
Graças à avaliação preguiçosa, a tarefa comum da paginação se torna bastante simples. Por exemplo, suponha que você tenha uma collection de resultados associada a uma query que corresponda a milhares de objeto em seu reconhecimento de data center. Você exibe cem objetos por página. Para avançar para qualquer página, basta acessar os elementos da collection de resultados começando pelo índice que corresponde à página de destino.
Ler objetos
A menos que indicado de outra forma, os exemplos nesta página usam dois Tipo de objeto de Realm, Person
e Team
.
()class _Person { () late ObjectId id; late String name; late List<String> hobbies; } ()class _Team { () late ObjectId id; late String name; late List<_Person> crew; late RealmValue eventLog; }
Encontrar objeto por chave primária
Encontre um objeto por sua chave primária com Realm.find().
final luke = realm.find<Person>(lukePrimaryKey);
query todos os objeto
Recupere uma coleção de todos os objetos de um modelo de dados no banco de dados com o método Realm.all() método.
final people = realm.all<Person>();
query relacionados a objeto
Novidade na versão 1.8.0.
Se o seu modelo de dados incluir objetos que referenciam outros objetos, você poderá consultar o relacionamento usando o getBacklinks() método.
Este método retorna uma coleção de resultados de todos os objetos que se vinculam ao objeto fornecido por meio de um relacionamento para-um, para-muitos ou inverso. Os exemplos a seguir usam os modelos definidos na página Relacionamentos .
Relacionamento para um: neste exemplo, temos um Realm Object Model
Bike
com um relacionamento para um com um objetoPerson
.Usamos o método
getBacklinks()
para encontrar quaisquer objetosBike
que estejam vinculados à pessoa especificada por meio da propriedadeowner
:// Persons have a to-one relationship with Bikes final person = realm.query<Person>("firstName == 'Anakin'").first; // Find all Bikes owned by a Person named 'Anakin' final allBikes = person.getBacklinks<Bike>('owner'); Relacionamento para muitos: neste exemplo, temos um Realm Object Model
Scooter
com um relacionamento para muitos com um objetoScooterShop
.Usamos o método
getBacklinks()
para encontrar quaisquer objetosScooterShops
vinculados à lambada especificada por meio da propriedade da listascooters
:// Scooters have a to-many relationship with ScooterShops final scooters = realm.query<Scooter>("name == 'Scooterbug'").first; // Find all ScooterShops with a Scooter named 'Scooterbug' final shops = scooters.getBacklinks<ScooterShop>('scooters'); Relacionamento inverso: neste exemplo, temos um modelo de objeto
Task
com um relacionamento inverso com um objetoUser
.Usamos o método
getBacklinks()
para encontrar qualquer objetoUser
que estejam vinculados às tarefas especificadas por meio da propriedade backlinktasks
:// Tasks have an inverse relationship to Users final inCompleteTasks = realm.query<Task>("isComplete == false"); // Find all Users who have an incomplete Task for (final task in inCompleteTasks) { final ownersWithIncompleteTasks = task.getBacklinks<User>('tasks'); for (final user in ownersWithIncompleteTasks) { print("User ${user.username} has incomplete tasks."); } }
Listas de query
Você pode executar query de qualquer lista de RealmObjects ou primitivos.
final config = Configuration.local([Person.schema, Team.schema]); final realm = Realm(config); final heroes = Team(ObjectId(), 'Millenium Falcon Crew', crew: [ Person(ObjectId(), 'Luke'), Person(ObjectId(), 'Leia'), Person(ObjectId(), 'Han'), Person(ObjectId(), 'Chewbacca') ]); realm.write(() => realm.add(heroes)); final lukeAndLeia = heroes.crew.query('name BEGINSWITH \$0', ['L']);
Consultar Coleções aninhadas de dados mistos
Novidades na versão 2.0.0.
No Flutter SDK v2.0.0 e posterior, as propriedades RealmValue podem conter coleções (uma lista ou mapa) de dados mistos. Essas collections podem ser aninhadas dentro de collections e podem conter outras collections de dados mistos.
Você pode consultá-los usando a mesma sintaxe que faria para uma lista normal ou coleção de dicionário. Consulte o documentação para obter mais informações sobre os operadores suportados e comparações de lista.
Para coleções aninhadas, você também pode usar:
Notação entre colchetes, que fornece os seguintes operadores de query de coleta:
[FIRST]
e [LAST
]: corresponda ao primeiro ou último elemento da coleção.[<int>]
: corresponde ao elemento no índice específico.[*]
: corresponde a qualquer elemento dentro da coleção (este operador assume um tipo de coleção nesse caminho).[SIZE]
: corresponda ao comprimento da coleção.
O operador
@type
, que suporta os seguintes valores:array
elist
: corresponde a uma coleção de listas.dictionary
eobject
: corresponde a uma coleção de mapas.collection
: corresponder a uma lista ou coleção de mapas.
realm.write(() { realm.addAll([ (Team(ObjectId(), 'Janitorial Staff', eventLog: RealmValue.from({ '1': { 'date': DateTime.utc(5622, 8, 18, 12, 30, 0), 'type': ['work_order', 'maintenance'], 'summary': 'leaking pipes in control room', 'priority': 'high', }, '2': { 'date': DateTime.utc(5622, 9, 18, 12, 30, 0), 'type': ['maintenance'], 'summary': 'trash compactor jammed', 'priority': 'low', 'comment': 'this is the second time this week' } }))), (Team(ObjectId(), 'IT', eventLog: RealmValue.from({ '1': { 'date': DateTime.utc(5622, 9, 20, 12, 30, 0), 'type': ['hardware', 'repair'], 'summary': 'lightsaber damage to server room', 'priority': 'high', } }))) ]); final teams = realm.all<Team>(); // Use bracket notation to query collection values at the specified path final teamsWithHighPriorityEvents = // Check any element at that path with [*] teams.query("eventLog[*].priority == 'high'"); print(teamsWithHighPriorityEvents.length); // prints `2` final teamsWithMaintenanceEvents = // Check for the first element at that path with [FIRST] teams.query("eventLog[*].type[FIRST] == 'maintenance'"); print(teamsWithMaintenanceEvents.length); // prints `1` final teamsWithMultipleEvents = // Check for collection at that path with matching elements // Note that the order must match unless you use ANY or ALL teams.query("eventLog[*].type[*] == {'maintenance', 'work_order'}"); print( teamsWithMultipleEvents.length); // prints `0` because order matters final teamsWithEventsAsLists = // Check the collection type with @type teams.query("eventLog[*].type.@type == 'list'"); print(teamsWithEventsAsLists.length); // prints `2` });
Converter listas ou conjuntos em resultados
Você pode converter um RealmList
ou RealmSet
para uma instância do RealmResults
utilizando seus respectivos métodos:
Estes métodos suportam listas e conjuntos de RealmObjects
, bem como valores primitivos.
final config = Configuration.local([Person.schema, Team.schema]); final realm = Realm(config); final heroes = Team(ObjectId(), 'Millenium Falcon Crew', crew: [ Person(ObjectId(), 'Luke', hobbies: [ 'Going to Tashi Station', 'Fixing the Moisture Vaporators' ]), Person(ObjectId(), 'Leia', hobbies: [ 'Going on diplomatic missions', 'Rescuing short stormtroopers' ]), Person(ObjectId(), 'Han', hobbies: ['Shooting first', 'Making fast Kessel Runs']), Person(ObjectId(), 'Chewbacca', hobbies: [ 'Fixing the Millenium Falcon', 'Tearing the arms off of droids' ]) ]); realm.write(() => realm.add(heroes)); // Converts the Team object's 'crew' List into a RealmResults<Person>. final heroesCrewAsResults = heroes.crew.asResults(); final luke = heroesCrewAsResults.query("name == 'Luke'").first; // Converts Luke's 'hobbies' list into a RealmResults<String> final lukeHobbiesAsResults = luke.hobbies.asResults();
Filtrar resultados
Filtre um RealmList
para recuperar um segmento específico de objetos com o método Realm.query() método. No argumento do método query()
, use RQL para executar a filtragem. O RQL é uma linguagem de query baseada em string que você pode usar para recuperar objetos do banco de dados.
final team = realm.query<Team>('name == \$0', ['Millennium Falcon Crew']).first; final humanCrewMembers = team.crew.query('name != \$0', ['Chewbacca']);
Você pode usar argumentos iteráveis em seu filtro. Por exemplo:
final listOfNames = ['Luke', 'Leia']; final matchingRealmObjects = realm.query<Person>('name IN \$0', [listOfNames]);
Filtrar relacionamentos inversos
Você também pode filtrar por relações inversas utilizando a sintaxe @links.<Type>.<Property>
. Por exemplo, um filtro pode corresponder a um objeto Task
com base nas propriedades do objeto User
que o referencia:
// Filter Tasks through the User's backlink property // using `@links.<ObjectType>.<PropertyName>` syntax final jarjarsIncompleteTasks = realm.query<Task>( "ALL @links.User.tasks.username == 'jarjar_binks' AND isComplete == false"); final tasksForHan = realm.query<Task>("ALL @links.User.tasks.username == 'han'");
Para obter mais informações sobre a construção de queries, consulte a documentação de referência da Realm Query Language.
Filtrar com pesquisa por texto completo
Você pode usar a RealmQL (RealmQL) para fazer uma query de propriedade que têm uma anotação de índice de pesquisa (FTS). Para executar queries destas propriedades, utilize o predicado TEXT
em sua query.
Exclua os resultados de uma palavra colocando o caractere -
na frente da palavra. Por exemplo, uma pesquisa para -sheep wool
incluiria todos os resultados da pesquisa para wool
excluindo aqueles com sheep
.
No SDK Flutter versão 1.6.0 e posterior, você pode especificar prefixos colocando o caractere *
no final de uma palavra. Por exemplo, wo*
incluiria todos os resultados de pesquisa para wool
e woven
. Atualmente, o SDK do Flutter não oferece suporte a pesquisas de sufixo.
No exemplo seguinte, querymos os campos Rug.pattern
e Rug.material
:
// Find rugs with a chevron pattern final chevronRugs = realm.query<Rug>("pattern TEXT \$0", ["chevron"]); // Find rugs with a wool material but not sheep wool final notSheepWoolRugs = realm.query<Rug>("material TEXT \$0", [" -sheep wool"]); // Find rugs with a material starting with "co-" final coRugs = realm.query<Rug>("material TEXT \$0", ["co*"]);
Full Text Search Tokenizer Details
Suporte a índices de pesquisa de texto completo (FTS):
Pesquisas de palavras correspondentes booleanas, não pesquisas por relevância.
Os tokens são diacríticos e não fazem distinção entre maiúsculas e minúsculas.
Os tokens só podem consistir em caracteres do ASCII e do suplemento Latin-1 (idiomas ocidentais).
Todos os outros caracteres são considerados espaços em branco. Palavras divididas por um hífen (-) como texto completo são divididas em dois tokens.
Para obter mais informações sobre os recursos do índice FTS, consulte a referência da API para RealmIndexType.
Classificar resultados
Classificar os resultados da query usando o operador RQL SORT() no argumento do método query()
.
Observe que você não pode usar queries parametrizadas em cláusulas RQL SORT(). Em vez disso, use strings ou interpolação de strings.
realm.write(() { realm.addAll([ Person(ObjectId(), 'Luke'), Person(ObjectId(), 'Leia'), Person(ObjectId(), 'Han'), Person(ObjectId(), 'Chewbacca') ]); }); final alphabetizedPeople = realm.query<Person>('TRUEPREDICATE SORT(name ASC)'); for (var person in alphabetizedPeople) { print(person.name); } // prints 'Chewbacca', 'Han', 'Leia', 'Luke'
Limitar resultados
Limite os resultados da consulta usando o operador Realm Query Language LIMIT() no argumento do método query()
.
Observe que você não pode usar queries parametrizadas em cláusulas RQL LIMIT(). Em vez disso, use strings ou interpolação de strings.
realm.write(() { realm.addAll([ Person(ObjectId(), 'Luke'), Person(ObjectId(), 'Luke'), Person(ObjectId(), 'Luke'), Person(ObjectId(), 'Luke') ]); }); final limitedPeopleResults = realm.query<Person>('name == \$0 LIMIT(2)', ['Luke']); // prints `2` print(limitedPeopleResults.length);