CRUD - 생성 - C++ SDK
이 페이지의 내용
쓰기 트랜잭션(write transaction)
Realm 은 매우 효율적인 storage engine 을 사용하여 객체를 유지합니다. Realm에서 객체를 생성 하고, Realm에서 객체를 업데이트 하고, 최종적으로 Realm에서 객체를 삭제할 수 있습니다. 이러한 작업은 Realm의 상태를 수정하기 때문에 쓰기 작업이라고 합니다.
Realm은 트랜잭션 측면에서 쓰기를 처리합니다. 트랜잭션은 Realm이 분할할 수 없는 단일 작업으로 처리하는 읽기 및 쓰기 작업 목록입니다. 다시 말해, 트랜잭션은 전부 아니면 아무것도 아닙니다: 트랜잭션의 모든 작업이 성공하거나 트랜잭션의 작업 중 어느 것도 적용되지 않습니다.
모든 쓰기는 트랜잭션에서 이루어져야 합니다.
Realm은 한 번에 하나의 열린 트랜잭션만 허용합니다. Realm은 열린 트랜잭션이 완료될 때까지 다른 스레드에서 다른 쓰기를 차단합니다. 따라서 트랜잭션 내의 영역에서 값을 읽을 때 경쟁 조건이 없습니다.
트랜잭션이 완료되면 Realm은 트랜잭션을 커밋 하거나 취소 합니다.
Realm이 트랜잭션을 커밋 하면 Realm은 모든 변경 사항을 디스크에 기록합니다. 동기화된 영역의 경우 SDK는 Atlas Device Sync와의 동기화를 위해 변경 사항을 대기열에 추가합니다.
Realm이 쓰기 트랜잭션(write transaction)을 취소 하거나 트랜잭션 작업에서 오류가 발생하면 모든 변경 사항이 삭제(또는 "롤백")됩니다.
새 객체 만들기
객체 생성
객체 를 만들려면 realm
네임스페이스 를 사용하여 객체를 인스턴스화해야 합니다. 쓰기 트랜잭션( 쓰기 트랜잭션 (write transaction) ) 내에서 Realm .add() 함수 영역 사용하여 객체 를 Realm으로 이동합니다.
객체를 Realm으로 이동하면 객체가 rvalue로 소비됩니다. 모든 데이터 액세스 또는 관찰에는 managed 객체를 사용해야 합니다. 이 예시에서 dog
객체를 영역에 복사하면 해당 객체가 rvalue로 사용됩니다. managed 객체를 반환하여 계속 작업할 수 있습니다.
// 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)); });
모델
객체 모델링에 대한 자세한 내용은 새 Realm 객체 유형 정의를 참조하세요.
namespace realm { struct Dog { std::string name; int64_t age; }; REALM_SCHEMA(Dog, name, age) } // namespace realm
내장된 객체 생성
포함된 객체를 만들려면 포함된 객체의 원시 포인터를 상위 객체의 속성에 할당합니다. 쓰기 트랜잭션(write transaction) 내에서 Realm.add() 함수 를 사용하여 상위 객체를 Realm으로 이동합니다.
이 예제에서는 내장된 객체의 원시 포인터( ContactDetails *
)를 상위 객체( Business.contactDetails
)의 내장된 객체 속성에 할당합니다.
그런 다음 business
객체를 Realm에 추가합니다. 이렇게 하면 business
및 contactDetails
객체가 영역에 복사됩니다.
ContactDetails
는 내장된 객체이므로 메인 Business
객체와 독립적인 자체 수명 주기가 없습니다. Business
객체를 삭제하면 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)); });
모델
내장된 객체 모델링에 대한 자세한 내용은 내장된 객체 정의를 참조하세요.
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
To-One 관계가 있는 객체 만들기
다른 객체와 to-one 관계를 가진 객체를 만들려면 관련 객체의 원시 포인터를 메인 객체의 관계 속성에 할당합니다. 쓰기 트랜잭션(write transaction) 내에서 Realm.add() 함수 를 사용하여 객체를 Realm으로 이동합니다.
이 예제에서는 관련 객체의 원시 포인터인 FavoriteToy *
를 메인 객체인 Dog.favoriteToy
의 관계 속성에 할당합니다. 그런 다음 dog
객체를 영역에 추가하면 dog
및 favoriteToy
가 모두 영역에 복사됩니다.
관련 favoriteToy
객체는 메인 dog
객체와 독립적인 자체 수명 주기를 가지고 있습니다. 메인 객체를 삭제해도 관련 객체는 남아 있습니다.
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)); });
선택적으로 관계 만들어 관련 객체 에서 기본 객체 를 참조할 수 있습니다. 자세한 내용 은 역관계가 있는 객체 생성을 참조하세요.
모델
대일 관계 모델링에 대한 자세한 내용은 대일 관계 정의를 참조하세요.
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)
대다(To-Many) 관계로 객체 만들기
하나 이상의 객체와 대다 관계가 있는 객체를 만들려면 다음을 수행합니다.
메인 객체 및 관련 객체 초기화
Realm 객체 목록에서 사용할 수 있는 push_back 멤버 함수를 사용하여 관련 객체의 원시 포인터를 메인 객체의 목록 속성에 추가합니다.
쓰기 트랜잭션(write transaction) 내에서 Realm.add() 함수 를 사용하여 객체를 Realm으로 이동합니다.
이 예제에서는 관련 객체의 원시 포인터인 Employee *
를 메인 객체의 관계 속성 Company.employees
에 추가합니다. 이렇게 하면 Company
객체에서 Employee
객체로의 단방향 연결이 생성됩니다.
그런 다음 영역에 Company
을(를) 추가합니다. 이렇게 하면 Company
및 Employee
객체가 영역에 복사됩니다.
관련 Employee
객체는 메인 Company
객체와 독립적인 자체 수명 주기를 가지고 있습니다. 메인 객체를 삭제해도 관련 객체는 남아 있습니다.
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)); });
선택적으로 관계 만들어 관련 객체 에서 기본 객체 를 참조할 수 있습니다. 자세한 내용 은 역관계가 있는 객체 생성을 참조하세요.
모델
대다 관계 모델링에 대한 자세한 내용은 대다 관계 정의를 참조하세요.
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)
역객체로 객체 만들기
다른 객체와 역관계가 있는 객체를 만들려면 관련 객체의 원시 포인터를 메인 객체의 관계 속성에 할당합니다. 쓰기 트랜잭션(write transaction) 내에서 Realm.add() 함수 를 사용하여 객체를 Realm으로 이동합니다.
이 예제에서는 동일한 Dog
객체에 대해 각각 대일 관계를 가진 두 개의 Person
객체를 생성합니다. Dog
는 각 Person
객체와 역관계를 갖습니다. 역관계 역링크는 연결된 Person
객체가 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);
모델
관계 모델링에 대한 자세한 내용은 관계 정의를 참조하세요.
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)
지도 속성을 사용하여 객체 생성
지도 속성 이 있는 객체를 만들 때 다음과 같은 몇 가지 방법으로 키 값을 설정할 수 있습니다.
객체에 키와 값을 설정한 다음 객체를 영역에 추가
쓰기 트랜잭션(write transaction) 내에서 직접 객체의 키와 값 설정
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; });
Realm에서는 지도 키에 .
또는 $
문자를 사용할 수 없습니다. 백분율 인코딩 및 디코딩을 사용하여 허용되지 않는 문자 중 하나가 포함된 지도 키를 저장할 수 있습니다.
// Percent encode . or $ characters to use them in map keys auto mapKey = "Monday.Morning"; auto encodedMapKey = "Monday%2EMorning";
모델
지원되는 지도 데이터 유형에 대한 자세한 내용은 지도/사전을 참조하세요.
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
속성 설정을 사용하여 객체 만들기
다른 Realm 객체와 마찬가지로 세트 속성이 포함된 객체를 만들 수 있지만 쓰기 트랜잭션(write transaction) 내에서만 세트 속성을 변경할 수 있습니다. 즉, 쓰기 트랜잭션(write transaction) 내에서는 설정된 속성의 값만 설정할 수 있습니다.
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); } });
모델
지원되는 집합 데이터 유형에 대한 자세한 내용은 집합을 참조하세요 .
namespace realm { struct Repository { std::string ownerAndName; std::set<int64_t> openPullRequestNumbers; }; REALM_SCHEMA(Repository, ownerAndName, openPullRequestNumbers) } // namespace realm
비대칭 객체 생성
데이터 수집 을 통해 Atlas App Services 앱에 연결된 Atlas 데이터베이스 에 단방향으로 동기화되는 비대칭 객체 를 생성할 수 있습니다. 비대칭 객체 에 로컬로 액세스 하거나 영역 에서 제거 하거나 쿼리 할 수 없습니다.
auto weatherSensorReading = realm::WeatherSensorReading{.deviceId = "WX1278UIT", .temperatureInFahrenheit = 64.7, .windSpeedInMph = 7}; realm.write([&] { realm.add(std::move(weatherSensorReading)); });
비대칭 객체 작업에 대한 자세한 내용은 Atlas로 데이터 스트리밍 - C++ SDK를 참조하세요.
모델
비대칭 객체 정의에 대한 자세한 내용은 비대칭 객체 정의를 참조하세요.
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)