资料
- www.cocoachina.com/articles/26… - iOS 数据持久化方案-Realm的使用
一、基础使用
1、创建想要存储的数据
-
.h文件:#import <Foundation/Foundation.h> #import <Realm/Realm.h> NS_ASSUME_NONNULL_BEGIN @interface LRUser : RLMObject @property (nonatomic , strong) NSString *userName; @property (nonatomic , assign) NSInteger userAge; @property (nonatomic , assign) NSInteger userId; // primaryKey - 主键 @end NS_ASSUME_NONNULL_END- 继承
RLMObject类后方可进行存储 - 若想使用主键,需先声明某个属性,之后在
.m文件中设置该属性为主键
- 继承
-
.m文件:#import "LRUser.h" @implementation LRUser /** 设置主键 */ + (NSString *)primaryKey { return @"userId"; } @end
2、基本的增删改查操作
-
【增】创建好数据文件后,即可在需要的时机进行数据的创建,一般的数据创建方式有两种:
-
在
init方法里一次性输入完数据:LRUser *user1 = [[LRUser alloc] initWithValue:@{@"userId":@1,@"userName":@"黄旭东"}]; //注意此处数字类型需要加 @ 符号 user1.userAge = 38; -
先创建数据对象,再逐步通过给属性赋值完善数据:
LRUser *user2 = [[LRUser alloc] init]; user2.userName = @"孙一峰"; user2.userAge = 36;LRUser *user3 = [[LRUser alloc] init]; user3.userId = 3; //注意此处数字类型不要加 @ 符号 // user3.userName = @"周宁"; user3.userAge = 36;-
如果有属性没有赋值,则会默认置为
0或(null) -
上述数据在数据库的存储为:
RLMResults<LRUser> <0x7f8e94415560> ( [0] LRUser { userName = 黄旭东; userAge = 38; userId = 1; }, [1] LRUser { userName = 孙一峰; userAge = 36; userId = 0; // 未设置 }, [2] LRUser { userName = (null); // 未设置 userAge = 36; userId = 3; } )
-
-
-
【增】创建好数据后需要将数据存入数据库:
-
获取默认的数据库:
RLMRealm *realm = [RLMRealm defaultRealm]; -
对数据进行更新:
[realm transactionWithBlock:^{ [realm addOrUpdateObject:user1]; [realm addOrUpdateObject:user2]; [realm addOrUpdateObject:user3]; }];可看出,此处使用的是
addOrUpdateObject:而不是addObject:- 因为在有主键的情况下,
[[LRUser alloc] init]不同于一般的对象创建,只会获取该主键对应的数据,以便对原主键对应的数据进行替换。 - 注:使用
[[LRUser alloc] init]后,如果开发者不对其属性进行赋值,则默认全部更新为0或(null),所以一般想只更新数据的某个属性,需要以其他方式获取数据,下方会详细说明 - 没有主键或主键不同时,使用
addObject:可重复添加相同的数据
- 因为在有主键的情况下,
-
-
【查】数据的查找与获取:
-
获取所有同类型的数据:
RLMResults<LRUser *> *users = [LRUser allObjects]; -
根据条件查找:
-
字符串
RLMResults<LRUser *> *users2 = [LRUser objectsWhere:@"userName = '周宁'"]; -
数字
RLMResults<LRUser *> *users = [LRUser objectsWhere:@"userAge > 36"];
-
-
对查询结果进行排序
RLMResults<LRUser *> *users3 = [LRUser allObjects]; NSLog(@"-- %@",users3); RLMResults *soreUsers3 = [users3 sortedResultsUsingKeyPath:@"userAge" ascending:YES]; // ascending:YES 为升序, NO为降序 NSLog(@"-- %@",soreUsers3);打印:
-- RLMResults<LRUser> <0x7f9a78c0f810> ( [0] LRUser { userName = 黄旭东; userAge = 38; userId = 1; }, [1] LRUser { userName = 孙一峰; userAge = 36; userId = 2; }, [2] LRUser { userName = 周宁; userAge = 36; userId = 3; } ) -- RLMResults<LRUser> <0x7f9a79e12dc0> ( [0] LRUser { userName = 孙一峰; userAge = 36; userId = 2; }, [1] LRUser { userName = 周宁; userAge = 36; userId = 3; }, [2] LRUser { userName = 黄旭东; userAge = 38; userId = 1; } )
-
-
【删】删除数据
-
删除单个数据:
[realm transactionWithBlock:^{ [realm deleteObject:user3]; }]; -
删除多个数据:
[realm transactionWithBlock:^{ [realm deleteObjects:users2]; }];
-
-
【改】更改数据
-
通过主键获取要修改的数据:
LRUser *user5 = [LRUser objectForPrimaryKey:@1];- 以该方法获取数据后,不允许直接对其属性进行赋值,需要在特定的Realm方法内部修改其属性,否则会报错
Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.
- 以该方法获取数据后,不允许直接对其属性进行赋值,需要在特定的Realm方法内部修改其属性,否则会报错
-
直接对数据的属性进行更新:
LRUser *user5 = [LRUser objectForPrimaryKey:@1]; RLMResults<LRUser *> *users3 = [LRUser allObjects]; NSLog(@"-- %@",users3); RLMRealm *realm = [RLMRealm defaultRealm]; [realm transactionWithBlock:^{ user5.userName = @"黄乌龟"; // 只更改了单一属性 }]; NSLog(@"-- %@",users3);打印结果为:
-- RLMResults<LRUser> <0x7ff66be0e120> ( [0] LRUser { userName = 黄旭东; userAge = 38; userId = 1; } ) -- RLMResults<LRUser> <0x7ff66be0e120> ( [0] LRUser { userName = 黄乌龟; userAge = 38; userId = 1; } )
-
-
【改】数据库迁移(适用于修改了数据模型的情况)
-
适用于修改了数据模型的情况:比如在一个模型里面我们删除了一个属性或者添加了一个属性的情况等等,结构发生了变化
-
在
application:didFinishLaunchingWithOptions:对数据库进行升级 -
升级代码为:
- (void)databaseMigration:(int)newVersion { // 1. 获取默认配置 RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; // 2. 叠加版本号(要比上一次的版本号高) 0 config.schemaVersion = newVersion; // 3. 设置闭包,这个闭包将会在打开低于上面所设置版本号的 Realm 数据库的时候被自动调用 [config setMigrationBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion) { // 什么都不要做!Realm 会自行检测新增和需要移除的属性,然后自动更新硬盘上的数据库架构 if (oldSchemaVersion < newVersion) { } }]; // 4. 让配置生效(告诉 Realm 为默认的 Realm 数据库使用这个新的配置对象) [RLMRealmConfiguration setDefaultConfiguration:config]; // // 5. 我们已经告诉了 Realm 如何处理架构的变化,打开文件之后将会自动执行迁移,数据结构会发生变化 // [RLMRealm defaultRealm]; }
-
-
\