-
cocopods 导入
platform :ios, '11.0' target 'TestRealm' do use_frameworks! pod 'Realm', '~> 10.15.0' end target 'TestRealmTests' do use_frameworks! pod 'Realm', '~> 10.15.0' end
2.使用
2.1 头文件 #import
2.2
#import
#import
NS_ASSUME_NONNULL_BEGIN
//注意这里属性的写法 不写策略
@interface Student : RLMObject
@property long num;
@property int age;
@property NSString *name;
@end
RLM_ARRAY_TYPE(Student)
NS_ASSUME_NONNULL_END
.m
#import "Student.h"
@implementation Student
// 主键
+(NSString*)primaryKey{
return @"num";
}
//+(NSDictionary*)defaultPropertyValues{
// return @{};
//}
//+(NSArray*)ignoredProperties{
// return @[];
//}
@end
3 操作
3.1 保存
创建一个对象
Student * stu2 = [[Student alloc]initWithValue:@{@"age":@(20),@"name":@"帅哥",@"num":@(4)}];
生成一rlm
RLMRealm * rlm = [RLMRealm defaultRealm];
保存和跟新
[rlm transactionWithBlock:^{
// [rlm addObject:stu]; //保存
[rlm addObject:stu2];//更新
[rlm addOrUpdateObject:stu2];//保存或者更新
}];
// 由于realm 有映射关系,下面的代码也能更新数据库表
[rlm transactionWithBlock:^{
stu.age = 30;
}];
3.2 查询
RLMResults
// 根据主键查找
Student* stu = [Student objectForPrimaryKey:@(1)];
[Student objectsInRealm:rlm withPredicate:@"age = 30"];
// 更具条件查找
RLMResults *results= [Student objectsWhere:@"age = 30"]
[Student objectsInRealm:rlm where:@"age = 30"];
RLMResults *results= [Student allObjects];
stu = results.fristObject;
// 由于realm 有映射关系,下面的代码也能更新数据库表
[rlm transactionWithBlock:^{
stu.age = 10;
}];
删除数据
注意: 删除的模型必须是数据库管理的,不能是自己创建的,应该是从数据库中读取的。
[rlm transactionWithBlock:^{
[rlm deleteObject:stu2];删除一个
[rlm deleteObjects:@[]];删除多个
[rlm deleteAllObjects];// 删除所有
}];
分页
第一个3 ,跳过3条
第二个3 ,是取3条
select * from db limit 3,3
兼容的数据类型
1.imge
用连个属性来表示,一个用来外界来读,一个imageData外界用来取
h 文件
@property NSData*imageData;
@property (readonly)UIImage *image;
m 文件
-(UIImage*)image{
return [UIImage imageWithData:self.imageData];
}
2 集合 NSArray 字典,集合都不支持,(用imge的方法,或者存字符串)
对应关系
####### 一对一
#import
#import
#import "Dog.h"
NS_ASSUME_NONNULL_BEGIN
@interface Student : RLMObject
@property long num;
@property int age;
@property NSString *name;
@property NSData*imageData;
@property (readonly)UIImage *image;
@property RLMArray *pet;
@end
RLM_ARRAY_TYPE(Student)
NS_ASSUME_NONNULL_END
#import "Student.h"
@implementation Student
-(UIImage*)image{
return [UIImage imageWithData:self.imageData];
}
+(NSString*)primaryKey{
return @"num";
}
//+(NSDictionary*)defaultPropertyValues{
// return @{};
//}
//+(NSArray*)ignoredProperties{
// return @[];
//}
@end
#import
#import
@class Student;
NS_ASSUME_NONNULL_BEGIN
@interface Dog : RLMObject
@property int num;
@property NSString *name;
@property (readonly) RLMLinkingObjects *master;//定义的这个类型 readlony 是会忽略的
@end
RLM_ARRAY_TYPE(Dog)
NS_ASSUME_NONNULL_END
#import "Dog.h"
@implementation Dog
+(NSDictionary *)linkingObjectsProperties{
return @{@"master":[RLMPropertyDescriptor descriptorWithClass:NSClassFromString(@"Student") propertyName:@"pets"]};//实现了这个,如果student 中的pets 中有这个dog的话,dog 中就会有一个student 反向的对应
}
@end
不能为空的属性
在.m 重实现这个协议,实现了这个协议,如果name 为nil 没有值,在写入数据库的时候会报错,修改的时候也不能改成空。
+(NSArray *)requiredProperties{
return @[@"name"];// name 必须有值
}
设置默认值
+(NSDictionary*)defaultPropertyValues{
return @{@"name":@"baby"};//
}
通知
@interface TestRealmTests : XCTestCase
// 保存属性
@property(nonatomic,strong)RLMNotificationToken *token;
@end
@implementation TestRealmTests
- (void)setUp {
[super setUp];
RLMRealm *real = [RLMRealm defaultRealm];
self.token = [real addNotificationBlock:^(RLMNotification _Nonnull notification, RLMRealm * _Nonnull realm) {
NSLog(@"接受到了通知 %@ %@",real,notification);
}];
// 这个通知更加牛 RLMCollectionChange 这里面有删除的,插入的,和改变的
self.token2 = [[Student allObjects]addNotificationBlock:^(RLMResults * _Nullable results, RLMCollectionChange * _Nullable change, NSError * _Nullable error) {
}];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
[self.token invalidate];
[super tearDown];
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void)testExample {
Student * stu = [[Student alloc]initWithValue:@{@"age":@(18),@"name":@"帅哥",@"num":@(1)}];
RLMRealm *real = [RLMRealm defaultRealm];
[real transactionWithBlock:^{
[real addOrUpdateObject:stu];//这里会发出通知
}];
[real transactionWithBlock:^{
stu.age = 30; // 这里也会发出通知
}];
用户机制
// 新增一个方法来改边存储表的名字
-(void)setDefaultRealmForuUser:(NSString*)userId{
RLMRealmConfiguration * config = [RLMRealmConfiguration defaultConfiguration];
config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:userId]URLByAppendingPathExtension:@"realm"];
[RLMRealmConfiguration setDefaultConfiguration:config];
}
使用
[self setDefaultRealmForuUser:@"王武"];
//这里调用的时候就更新林要操作的表的名字
RLMRealm *real = [RLMRealm defaultRealm];
后面通过调用realm 来操作
删除指定用户的数据库
就是删除指定目录下的文件
-(void)testDelete{
[self setDefaultRealmForuUser:@"lisi"];
NSFileManager *fileManger = [NSFileManager defaultManager];
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
NSArray*realmfileUrls = @[config.fileURL,
[config.fileURL URLByAppendingPathExtension:@"lock"],
[config.fileURL URLByAppendingPathExtension:@"management"],
[config.fileURL
];
for (NSURL *url in realmfileUrls) {
[fileManger removeItemAtPath:url error:nil];
}
}
数据库的迁移
RLMRealmConfiguration * config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
[config setMigrationBlock:^(RLMMigration * _Nonnull migration, uint64_t oldSchemaVersion) {
if (config.schemaVersion > oldSchemaVersion) {
这里不需要做什么就会自动实现数据迁移
//更名操作,将Student 中的name1 改成name2
[migration renamePropertyForClass:@"Student" oldName:@"name1" newName:@"name2"];
// 下面的操作是将 Student模型中的fullNmae 用老的name1 和老的name2 的数据拼接起来,到达数据库迁移的时候合成fullNmae 的值
[migration enumerateObjects:@"Student" block:^(RLMObject * _Nullable oldObject, RLMObject * _Nullable newObject) {
newObject[@"fullNmae"] = [NSString stringWithFormat:@"%@%@",oldObject[@"name1"],oldObject[@"name2"]];
}]
}
}];
[RLMRealmConfiguration setDefaultConfiguration:config];
[RLMRealm defaultRealm];