在以前的项目中数据库是使用的FMDB,数据字段在工程中是用OC对象进行引用的,如果要添加字段需要在数据库、OC对象两个地方添加,不是很方便,既然数据是以OC对象展示的,那为何不能通过修改OC对象达到修改数据库字段的目的呢?由于见识有限,当时也没有细想如何达到这样的目的,在时隔一年之后在看了Realm,发现他就是用这样的方式进行数据库操作的,而且看了他的API,还是比较简单的,顺带手的就学习了,现记录如下。
realm提供了三种创建数据库的方法,如下所示
1. 使用默认的数据库
realm为使用者提供了一个默认的数据库,defaultRealm。通过调用 [RLMRealm defaultRealm] 来初始化以及访问我们的 realm 变量。
2.自己定义数据库
2.1使用RLMRealmConfiguration提供的弄人数据库位置并设置数据库的名字、readonly属性等等
1 2 3 4 5 6 7 8 9
| RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.path = [[[config.path stringByDeletingLastPathComponent] stringByAppendingPathComponent:yourDataBaseName] stringByAppendingPathExtension:@"realm"];
[RLMRealmConfiguration setDefaultConfiguration:config];
|
Note:这里在进行配置的时候还有一个可选方法,传递config
以及error
,你应该一直传入error以捕获由于内存爆掉、设置错误等报错信息的出现
2.2不使用RLMRealmConfiguration提供的path
1 2 3
| NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *dbPath = [docPath stringByAppendingPathComponent:@"db/yourDataBaseName.realm"]; RLMRealm *realm = [RLMRealm realmWithPath:dbPath readOnly:YES error:nil];
|
3.创建一个内存数据库
一般的realm数据库是存储在硬盘上的,但有时候也需要在内存中创建一个数据库,可以使用如下方法进行创建。
1 2 3 4 5 6 7
| RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration] config.inMemoryIdentifier = @"yourInMemoryDataBase" RLMRealm *realm = [RLMRealm realmWithConfiguration:config]
or
RLMRealm *realm = [RLMRealm inMemoryRealmWithIdentifier:@"yourInMemoryDataBase"]
|
Note:内存数据库在每次程序退出时不会保存数据。如果某个内存Realm实例没有被引用,所有的数据在实例对象释放的适合也会被释放。建议你在app中用强引用来钳制所有新建的内存Realm数据库实例。
二、Realm数据库的数据库迁移以及更新
当数据库版本有改动的时候,在以往的数据库管理方法中是将数据库中的字段进行修改,然后才能进行新版本的数据库的使用。而realm的数据库模型是用OC对来定义的数据库,所以在修改数据库的时候只进行realm对象的修改就能够达到目的,这是很方便的。
现在假设有一个realm模型
1 2 3 4 5 6
| @interface Person : RLMObject @property NSString *firstName; @property NSString *lastName; @property int age; @end
|
在v0.1版本中由于逻辑的改变,需要将firstName
以及lastName
合并成一个fullName
字段,在模型中我们只需要添加如下一个属性即可,如下
1 2 3 4 5
| @interface Person : RLMObject @property NSString *fullName; @property int age; @end
|
如果在v0.2版本中又新增加一个属性email
1 2 3 4 5 6
| @interface Person : RLMObject @property NSString *fullName; @property NSString *email; @property int age; @end
|
但是这时候realm数据库中的字段还是没有修改的,我们要做的是通知数据库,某些字段和某些字段发生了某些变化,如果在这之前你尝试更新之前就保存的数据的话,数据库就会报错,因为数据库中没有fullName
字段。这时候就需要使用数据库迁移。
realm提供了RLMRealmConfiguration的schemaVersion
NSInteger属性以及migrationBlock
block属性定义一个迁移操作以及与之关联的架构版本。 每当通过配置创建完一个 RLMRealm之后,迁移闭包将会在迁移需要的时候,将给定的架构版本应用到更新 RLMRealm 操作中。
ok,下面进行迁移的操作,下面是一个最简单的迁移操作模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) { if (oldSchemaVersion < 1) { } };
[RLMRealmConfiguration setDefaultConfiguration:config];
[RLMRealm defaultRealm];
|
进行v0.1版本的数据库更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; config.schemaVersion = 1; config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) { if (oldSchemaVersion < 1) { [migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@", oldObject[@"firstName"], oldObject[@"lastName"]]; }]; } }; [RLMRealmConfiguration setDefaultConfiguration:config];
|
在0.2版本中的迁移逻辑大概就是这样,记得先设置好schemaVersion
为当前版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; config.schemaVersion = 2; config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) { [migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) { if (oldSchemaVersion < 1) { newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@", oldObject[@"firstName"], oldObject[@"lastName"]]; }
if (oldSchemaVersion < 2) { newObject[@"email"] = @""; } }]; }; [RLMRealmConfiguration setDefaultConfiguration:config];
[RLMRealm defaultRealm];
|