CRUD - Criar - C++ SDK
Nesta página
- Transações de gravação
- Criar um novo objeto
- Criar um objeto
- Criar um Objeto Embarcado
- Crie um objeto com um relacionamento para um
- Crie um objeto com um relacionamento para muitos
- Crie um objeto com um relacionamento inverso
- Criar um objeto com uma propriedade de mapa
- Criar um objeto com uma propriedade de conjunto
- Criar um objeto assimétrico
Transações de gravação
Realm usa um storage engine altamente eficiente para persistir objetos. Você pode criar objetos em um realm, atualizar objetos em um realm e, eventualmente, excluir objetos de um realm. Como essas operações modificam o estado do realm, as chamamos de gravações.
O Realm lida com as operações de escrita como transações. Uma transação é um conjunto de operações de leitura e escrita que o Realm trata como uma única operação indivisível. Em outras palavras, uma transação é tudo ou nada: ou todas as suas operações na transação são bem-sucedidas ou nenhuma é efetivada.
Todas as operações de gravação devem ocorrer em uma transação.
Um domínio permite apenas uma transação aberta por vez. O Realm bloqueia outras escritas em outras threads até que a transação aberta seja concluída. Consequentemente, não há condição de corrida ao ler valores do domínio dentro de uma transação.
Quando você termina a transação, o Realm ou a confirma ou a cancela :
Quando o Realm confirma uma transação, o Realm grava todas as alterações no disco. Para domínios sincronizados, o SDK classifica a alteração para sincronização com Atlas Device Sync.
Quando Realm o domínio cancela transação de escrita ou uma operação na transação causa um erro, todas as alterações são descartadas (ou "revertidas").
Criar um novo objeto
Criar um objeto
Para criar um objeto, você deve instancia-lo usando o namespace realm
. Mova o objeto para o Realm usando a função Realm.add() dentro de uma transação de gravação.
Quando você move um objeto para um Realm, isso consome o objeto como um rvalue. Você deve usar o managed objeto para qualquer acesso ou observação de dados. Neste exemplo, copiar o objeto dog
para o Realm consome-o como um rvalue. Você pode retornar o managed objeto para continuar trabalhando com ele.
// Create an object using the `realm` namespace. auto dog = realm::Dog{.name = "Rex", .age = 1}; std::cout << "dog: " << dog.name << "\n"; // Open the database with compile-time schema checking. auto config = realm::db_config(); auto realm = realm::db(std::move(config)); // Persist your data in a write transaction // Optionally return the managed object to work with it immediately auto managedDog = realm.write([&] { return realm.add(std::move(dog)); });
Modelo
Para obter mais informações sobre como modelar um objeto, consulte: Definir um novo tipo de objeto.
namespace realm { struct Dog { std::string name; int64_t age; }; REALM_SCHEMA(Dog, name, age) } // namespace realm
Criar um Objeto Embarcado
Para criar um objeto embarcado, atribua o ponteiro bruto do objeto embarcado à propriedade de um objeto pai. Mova o objeto principal para o domínio usando a função Realm.add() dentro de uma transação de escrita.
Neste exemplo, atribuímos o ponteiro bruto do objeto incorporado - ContactDetails *
- à propriedade do objeto incorporado do objeto pai - Business.contactDetails
.
Em seguida, adicionamos o objeto business
ao realm. Isso copia o objeto business
e contactDetails
para o Realm.
Como o ContactDetails
é um objeto embarcado, ele não tem seu próprio ciclo de vida independente do objeto Business
principal. Se você excluir o objeto Business
, isso também excluirá o objeto ContactDetails
.
auto config = realm::db_config(); auto realm = realm::db(std::move(config)); auto contactDetails = realm::ContactDetails{ .emailAddress = "email@example.com", .phoneNumber = "123-456-7890"}; auto business = realm::Business(); business._id = realm::object_id::generate(); business.name = "MongoDB"; business.contactDetails = &contactDetails; realm.write([&] { realm.add(std::move(business)); });
Modelo
Para obter mais informações sobre como modelar um objeto incorporado, consulte: Definir um objeto incorporado.
namespace realm { struct ContactDetails { // Because ContactDetails is an embedded object, it cannot have its own _id // It does not have a lifecycle outside of the top-level object std::string emailAddress; std::string phoneNumber; }; REALM_EMBEDDED_SCHEMA(ContactDetails, emailAddress, phoneNumber) struct Business { realm::object_id _id; std::string name; ContactDetails *contactDetails; }; REALM_SCHEMA(Business, _id, name, contactDetails) } // namespace realm
Crie um objeto com um relacionamento para um
Para criar um objeto com uma relação para-um com outro objeto, atribua o ponteiro bruto do objeto relacionado à propriedade de relação do objeto principal. Mova o objeto para o domínio usando a função Realm.add() dentro de uma transação de escrita.
Neste exemplo, atribuímos o ponteiro bruto do objeto relacionado - FavoriteToy *
- à propriedade de relacionamento do objeto principal - Dog.favoriteToy
. Então, quando adicionamos o objeto dog
ao realm, isso copia o dog
e o favoriteToy
para o realm.
O objeto favoriteToy
relacionado tem seu próprio ciclo de vida independente do objeto dog
principal. Se você excluir o objeto principal, o objeto relacionado permanecerá.
auto config = realm::db_config(); auto realmInstance = realm::db(std::move(config)); auto favoriteToy = realm::FavoriteToy{ ._id = realm::uuid("68b696c9-320b-4402-a412-d9cee10fc6a5"), .name = "Wubba"}; auto dog = realm::Dog{ ._id = realm::uuid("68b696d7-320b-4402-a412-d9cee10fc6a3"), .name = "Lita", .age = 10, .favoriteToy = &favoriteToy}; realmInstance.write([&] { realmInstance.add(std::move(dog)); });
Opcionalmente, você pode criar um relacionamento inverso para fazer referência ao objeto principal a partir do objeto relacionado. Para obter mais informações, consulte: Criar um objeto com um relacionamento inverso.
Modelo
Para obter mais informações sobre como modelar um relacionamento para um, consulte: Definir um relacionamento para um.
struct FavoriteToy { realm::primary_key<realm::uuid> _id; std::string name; }; REALM_SCHEMA(FavoriteToy, _id, name) struct Dog { realm::primary_key<realm::uuid> _id; std::string name; int64_t age; // Define a relationship as a link to another SDK object FavoriteToy* favoriteToy; }; REALM_SCHEMA(Dog, _id, name, age, favoriteToy)
Crie um objeto com um relacionamento para muitos
Para criar um objeto com um relacionamento para-muitos com um ou mais objeto:
Inicialize o objeto principal e os objetos relacionados
Use a função de membro push_back disponível para as listas de objetos de Realm para anexar os ponteiros brutos dos objetos relacionados à propriedade de lista do objeto principal
Mova o objeto para o domínio usando a função Realm.add() dentro de uma transação de escrita.
Neste exemplo, anexamos os ponteiros brutos dos objetos relacionados - Employee *
- à propriedade de relacionamento do objeto principal - Company.employees
. Isso cria uma conexão unidirecional do objeto Company
para os objetos Employee
.
Em seguida, adicionamos o Company
ao Realm. Isso copia o objeto Company
e Employee
para o Realm.
Os objetos Employee
relacionados têm seu próprio ciclo de vida independente do objeto Company
principal. Se você excluir o objeto principal, os objetos relacionados permanecerão.
auto config = realm::db_config(); auto realmInstance = realm::db(std::move(config)); auto employee1 = realm::Employee{ ._id = 23456, .firstName = "Pam", .lastName = "Beesly"}; auto employee2 = realm::Employee{ ._id = 34567, .firstName = "Jim", .lastName = "Halpert"}; auto company = realm::Company{._id = 45678, .name = "Dunder Mifflin"}; // Use the `push_back` member function available to the // `ListObjectPersistable<T>` template to append `Employee` objects to // the `Company` `employees` list property. company.employees.push_back(&employee1); company.employees.push_back(&employee2); realmInstance.write([&] { realmInstance.add(std::move(company)); });
Opcionalmente, você pode criar um relacionamento inverso para fazer referência ao objeto principal a partir do objeto relacionado. Para obter mais informações, consulte: Criar um objeto com um relacionamento inverso.
Modelo
Para obter mais informações sobre como modelar um relacionamento para muitos, consulte: Definir um relacionamento para muitos.
namespace realm { struct Employee { realm::primary_key<int64_t> _id; std::string firstName; std::string lastName; // You can use this property as you would any other member // Omitting it from the schema means the SDK ignores it std::string jobTitle_notPersisted; }; // The REALM_SCHEMA omits the `jobTitle_notPersisted` property // The SDK does not store and cannot retrieve a value for this property REALM_SCHEMA(Employee, _id, firstName, lastName) } // namespace realm
struct Company { int64_t _id; std::string name; // To-many relationships are a list, represented here as a // vector container whose value type is the SDK object // type that the list field links to. std::vector<Employee*> employees; }; REALM_SCHEMA(Company, _id, name, employees)
Crie um objeto com um relacionamento inverso
Para criar um objeto com um relacionamento inverso com outro objeto, atribua o ponteiro bruto do objeto relacionado à propriedade relacionamento do objeto principal. Mova o objeto para o domínio usando a função Realm.add() dentro de uma transação de escrita.
Neste exemplo, criamos dois objeto Person
que cada um tem um relacionamento para-um com o mesmo objeto Dog
. O Dog
tem um relacionamento inverso para cada objeto Person
. O backlink de relacionamento inverso é atualizado automaticamente quando um objeto Person
vinculado atualiza seu relacionamento Dog
.
auto config = realm::db_config(); auto realm = realm::db(std::move(config)); auto dog = realm::Dog{.name = "Bowser"}; auto [jack, jill] = realm.write([&realm]() { auto person = realm::Person{.name = "Jack", .age = 27, .dog = nullptr}; realm::Person person2; person2.name = "Jill"; person2.age = 28; person2.dog = nullptr; return realm.insert(std::move(person), std::move(person2)); }); realm.write([&dog, jack = &jack]() { jack->dog = &dog; }); // After assigning `&dog` to jack's `dog` property, // the backlink automatically updates to reflect // the inverse relationship through the dog's `owners` // property CHECK(jack.dog->owners.size() == 1); realm.write([&dog, jill = &jill]() { jill->dog = &dog; }); // After assigning the same `&dog` to jill's `dog` // property, the backlink automatically updates CHECK(jill.dog->owners.size() == 2); CHECK(jack.dog->owners.size() == 2); // Removing the relationship from the parent object // automatically updates the inverse relationship realm.write([jack = &jack]() { jack->dog = nullptr; }); CHECK(jack.dog == nullptr); CHECK(jill.dog->owners.size() == 1);
Modelo
Para obter mais informações sobre como modelar um relacionamento inverso, consulte: Definir um relacionamento inverso.
struct Dog; struct Person { realm::primary_key<int64_t> _id; std::string name; int64_t age = 0; Dog* dog; }; REALM_SCHEMA(Person, _id, name, age, dog) struct Dog { realm::primary_key<int64_t> _id; std::string name; int64_t age = 0; linking_objects<&Person::dog> owners; }; REALM_SCHEMA(Dog, _id, name, age, owners)
Criar um objeto com uma propriedade de mapa
Ao criar um objeto que tenha uma propriedade map, você pode definir os valores para chaves de algumas maneiras:
Definir chaves e valores no objeto e depois adicionar o objeto ao domínio
Definir as chaves e os valores do objeto diretamente dentro de uma transação de escrita
auto config = realm::db_config(); auto realm = realm::db(std::move(config)); auto employee = realm::Employee{ ._id = 8675309, .firstName = "Tommy", .lastName = "Tutone"}; employee.locationByDay = { {"Monday", realm::Employee::WorkLocation::HOME}, {"Tuesday", realm::Employee::WorkLocation::OFFICE}, {"Wednesday", realm::Employee::WorkLocation::HOME}, {"Thursday", realm::Employee::WorkLocation::OFFICE}}; realm.write([&] { realm.add(std::move(employee)); employee.locationByDay["Friday"] = realm::Employee::WorkLocation::HOME; });
O Realm não permite o uso de .
ou $
caracteres em chaves de mapa. Você pode usar a codificação e a decodificação percentual para armazenar uma chave de mapa que contenha um desses caracteres não permitidos.
// Percent encode . or $ characters to use them in map keys auto mapKey = "Monday.Morning"; auto encodedMapKey = "Monday%2EMorning";
Modelo
Para mais informações sobre os tipos de dados de mapa suportados, consulte: Mapa/Dicionário.
namespace realm { struct Employee { enum class WorkLocation { HOME, OFFICE }; int64_t _id; std::string firstName; std::string lastName; std::map<std::string, WorkLocation> locationByDay; }; REALM_SCHEMA(Employee, _id, firstName, lastName, locationByDay) } // namespace realm
Criar um objeto com uma propriedade de conjunto
Você pode criar objetos que contenham propriedades de conjunto como faria com qualquer objeto do Realm, mas só pode alterar uma propriedade de conjunto em uma transação de escrita. Isso significa que você só pode definir o(s) valor(es) de uma propriedade definida em uma transação de escrita.
auto realm = realm::db(std::move(config)); // Create an object that has a set property auto docsRealmRepo = realm::Repository{.ownerAndName = "mongodb/docs-realm"}; // Add the object to the database and get the managed object auto managedDocsRealm = realm.write([&]() { return realm.add(std::move(docsRealmRepo)); }); // Insert items into the set auto openPullRequestNumbers = {3059, 3062, 3064}; realm.write([&] { for (auto number : openPullRequestNumbers) { // You can only mutate the set in a write transaction. // This means you can't set values at initialization, // but must do it during a write. managedDocsRealm.openPullRequestNumbers.insert(number); } });
Modelo
Para obter mais informações sobre os tipos de dados de conjunto suportados, consulte: Conjunto.
namespace realm { struct Repository { std::string ownerAndName; std::set<int64_t> openPullRequestNumbers; }; REALM_SCHEMA(Repository, ownerAndName, openPullRequestNumbers) } // namespace realm
Criar um objeto assimétrico
Você pode criar um objeto assimétrico que sincroniza unidirecionalmente via ingestão de dados para o banco de banco de dados do Atlas vinculado ao seu Atlas App Services . Você não pode acessar um objeto assimétrico localmente, removê-lo de um Realm ou consultá-lo.
auto weatherSensorReading = realm::WeatherSensorReading{.deviceId = "WX1278UIT", .temperatureInFahrenheit = 64.7, .windSpeedInMph = 7}; realm.write([&] { realm.add(std::move(weatherSensorReading)); });
Para obter mais informações sobre como trabalhar com objetos assimétricos, consulte Stream Data to Atlas - C++ SDK.
Modelo
Para obter mais informações sobre como definir um objeto assimétrico, consulte: Definir um objeto assimétrico.
struct WeatherSensorReading { realm::primary_key<realm::object_id> _id{realm::object_id::generate()}; std::string deviceId; double temperatureInFahrenheit; int64_t windSpeedInMph; }; REALM_ASYMMETRIC_SCHEMA(WeatherSensorReading, _id, deviceId, temperatureInFahrenheit, windSpeedInMph)