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降序];
上一篇 下一篇

猜你喜欢

热点阅读