Realm数据库使用
2017-11-05 本文已影响22人
Vijay_
- 注意@property RLMArray<YPCar> *oldcars;定义属性时 这里不是泛型 而是协议!!!
- 所有字段前建议不要加引用修饰符
- RLMArray<$RLMObject>类型属性不要初始化,该属性是懒加载的 会自动初始化,直接使用就可以
官方文档
官方文档地址
修改表结构(数据库模型)
// 先拿到当前的配置对象
RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
// 设置配置对象的版本号为一个新的版本号
config.schemaVersion = 4;
// 设置迁移block
config.migrationBlock = ^(RLMMigration * _Nonnull migration, uint64_t oldSchemaVersion) {
NSLog(@"%llu",oldSchemaVersion);
// 遍历当前版本的VJRealmModel模型
[migration enumerateObjects:VJRealmModel.className block:^(RLMObject * _Nullable oldObject, RLMObject * _Nullable newObject) {
// 如果当前版本号小于设置的新版本号则为上一个版本号
if (oldSchemaVersion<4) {
// 即修改id字段为一个字符串类型
newObject[@"id"] = @"";
// !! newObject[$property]如果字段原来没有则新增 如果原来有则替换
// !! 需要设置该字段为什么类型给它赋什么类型的值就可以
newObject[@"name"] = @"";
};
}];
};
// !! 注意 设置完后要记得把设置好的配置对象替换给当前进程配置对象
[RLMRealmConfiguration setDefaultConfiguration:config];
// !! 只有开启realm操作时才会调用上面配置对象中设置的迁移block
RLMRealm* realm = [RLMRealm defaultRealm];
VJRealmModel* model = [[VJRealmModel alloc] init];
model.id = [[NSUUID UUID]UUIDString] ;
model.name = @"hello";
[realm beginWriteTransaction];
[realm deleteAllObjects];
[realm addObject:model];
[realm commitWriteTransaction];
创建数据
- (void)createDataBase:(NSString*)dataBaseName{
// 在用户域中找到文件documents目录
NSArray* arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* path = [arr firstObject];
// 在用户documents目录字符串后面添加/$dataBaseName.realm
// 例:/Users/jiewang/3E3E4E24-849E-4476-B776-E809C102355C/Documents/vijayData
NSString* filePath = [path stringByAppendingPathComponent:[dataBaseName stringByAppendingString:@".realm"]];
YPLog(@"%@",filePath);
RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
config.readOnly = NO;
NSInteger currentSchemaVersion = 1.0;
config.schemaVersion = currentSchemaVersion;
config.fileURL = [NSURL URLWithString:filePath];
config.migrationBlock = ^(RLMMigration * _Nonnull migration, uint64_t oldSchemaVersion) {
if (oldSchemaVersion < currentSchemaVersion) {
// 数据迁移block
}
};
[RLMRealmConfiguration setDefaultConfiguration:config];
YPLog(@"%@" ,[RLMRealmConfiguration defaultConfiguration].fileURL);
}
关于RLMObject的关系
- 一对多关系
# Realm数据库不支持NSArray所以需要用宏来声明一个RLMArray类型
//声明一个RLMArray属性
@property RLMArray<VJCar> *cars;
//对应的类需要声明RLMArray类型
RLM_ARRAY_TYPE(VJCar) // 定义RLMArray<VJCar>
- 一对一关系
//可以直接引用指定的类作为属性 只要继承了RMLObject类的类都可以作为一对一关系
@property VJRealmModel* owner;
- 多对多
# RLM数据库链性是单向的,所以不是真的双向引用只是互相单向引用了
# 由于两个类都要互相引用当互相引用.h文件时会报错
#import <Realm/Realm.h>
RLM_ARRAY_TYPE(VJCar) // 定义RLMArray<VJCar>
RLM_ARRAY_TYPE(VJRealmModel) // 定义RLMArray<RLMUser>
@interface VJRealmModel : RLMObject
@property NSString* id;
@property NSString* name;
@property RLMArray<VJCar> *cars;
@end
@interface VJCar : RLMObject
@property NSString* carName;
@property NSString* id;
@property VJRealmModel* owner;
@property RLMArray<VJRealmModel>* peoples;
//所以需要写在一个.h文件中
- 属性设置
#import "VJRealmModel.h"
@implementation VJRealmModel
//主键
+ (NSString *)primaryKey{
return @"id";
}
//忽略的属性
+ (NSArray<NSString *> *)ignoredProperties{
return @[@"hey"];
}
//索引
+ (NSArray<NSString *> *)indexedProperties{
return @[@"id"];
}
//非空属性
+ (NSArray<NSString *> *)requiredProperties{
return @[@"cars"];
}
//属性默认值设置
+ (NSDictionary *)defaultPropertyValues{
return @{@"oops":@"oops"};
}
@end
关于线程
#1.官方给出了一个建议:
//由于 Realm 采用了 MVCC 设计架构,
//读取操作并不会因为写入事务正在进行而受到影响。
//除非您需要立即使用多个线程来同时执行写入操作,
//不然您应当采用批量化的写入事务,而不是采用多次少量的写#入事务。
[realm transactionWithBlock:^{
[realm addObject: Car];
}];
#2.[RLMRealm defaultRealm]是获取当前线程的realm数据库上下文
#所以当在不同线程时需要获取不同的上下文对象 不能跨线程访问
增删改查函数
RLMRealm* realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
//增
[realm addObject:$RLMObject];
[realm addObjects:@[$RLMObject]];
//删
[realm deleteAllObjects]; //删除数据库所有对象
[realm deleteObject:$RLMObject];
[realm deleteObjects:@[$RLMObject]];
//改
[[model.cars objectAtIndex:0] setCarName:@"火车"];
[realm addOrUpdateObject:model];//如果该对象已存在则修改 不存在则为添加
[realm addOrUpdateObjects:@[$RLMObject]];//批量
//查
#注:RLMResult需要设置泛型 不然不能调用返回的对象的方法
#RLMResult<$泛型*>* result
#查询是懒加载 只有使用对象时才会执行查询 查询出来的对象如果在事务中进行了修改 当事务提交时会修改数据库 类似hibernate
#不能跨线程访问realm
//使用NSPredicate查询
NSPredicate* pred = [NSPredicate predicateWithFormat:@"carName = %@ AND id = %@",@"火车",@"E295BECA-AE78-4A67-8946-B47C760B69DE"];
RLMResults<VJCar*>* results = [VJCars objectsWithPredicate:pred];
NSLog(@"%@",[results objectAtIndex:0]);
}]
//使用断言查询 注意参数需要用单引号
RLMResults<VJCar*>* results = [VJCar objectsWhere:@"carName = '火车'"];
//查询所有数据
RLMResults<VJCar*>* results= [VJCar allObjects];
//排序查询
RLMResults<VJRealmModel*>* results =
[[VJRealmModel objectsWhere:@"oops = 'oops'"]
sortedResultsUsingKeyPath:@"$property" ascending:$YES升序NO降序];