首页 > 代码库 > Realm数据库的简单介绍和使用

Realm数据库的简单介绍和使用

给大家介绍一个数据库操作的框架Realm,本文主要以iOS 平台的使用场景为例。

realm是一个跨平台移动数据库引擎,支持iOS、OS X(Objective-C和Swift)以及Android;

核心数据引擎由C++打造,并不是建立在SQLite之上的ORM, 拥有独立的数据库存储引擎;

据官方称性能上比sqlite, coredata牛逼,而且使用起来更加简单, 更易入门。

下载地址:https://realm.io/cn/

使用教程:https://realm.io/docs/objc/latest/

 

辅助工具:

1、Realm Browser:可视化访问 Realm 数据库。

2、Xcode插件:可以快速创建Realm可存储模型对象。https://github.com/alcatraz/Alcatraz

 

开始Realm实战:

 

为了帮助您更好地理解 Realm 的使用,下面我们将会对 Realm 的相关术语和主要类进行一个大致的介绍:

 

  • RLMRealm : RLMRealm 是框架的核心所在,是我们构建数据库的访问点,就如同 Core Data 的管理对象上下文( managed  object context )一样。出于简单起见, realm 提供了一个名为 defaultRealm 的单例,在本教程中我们就仅使用这个单例来完成我们所需的功能。当然,我们也可以导入外部已经编写好的 realm 数据库文件,也可以在我们不需要将数据保存在硬盘上时使用 “ 内存实例对象 ” ( in-memory realm instance ),此外,还可以同时使用多个数据库文件。

  • RLMObject :这是我们自定义的 realm 数据模型。创建数据模型的行为将会影响到数据库的结构。要创建一个数据模型,我们只需要继承 RLMObject ,然后设计我们想要存储的属性即可。

  • 关系 (Relationships) :通过简单地在数据模型中声明一个 RLMObject 类型的属性,我们就可以创建一个 “ 一对多 ” 的对象关系。同样地,借助 RLMArray 我们还可以创建 “ 多对一 ” 和 “ 多对多 ” 的关系。

  • 写操作事务 (Write Transactions) :数据库中的所有操作,比如创建、编辑,或者删除对象,都必须在事务中完成。 “ 事务 ” 是指位于 beginWriteTransaction() 以及 commitWriteTransaction() 操作之间的代码段。

  • 查询 (Queries) :要在数据库中检索信息,我们需要用到 “ 检索 ” 操作。检索最简单的形式是对 RLMObject 对象发送 allObjects() 消息。如果需要检索更复杂的数据,那么还可以使用断言( predicates )、复合查询以及结果排序等等操作。

  • RLMResults :这个类是执行任何查询请求后所返回的类,其中包含了一系列的 RLMObjects 对象。和 NSArray 类似,我们可以用下标语法来对其进行访问,并且还可以决定它们之间的关系。不仅如此,它还拥有许多更强大的功能,包括排序、查找等等操作。

 

1.简单的数据操作

1.1准备: 创建数据模型, 继承自RLMObject

创建对象的方式:1. 普通创建;2. 通过父类RLMObject中的方法快速创建 initWithValue。

请注意,所有的必需属性都必须在对象添加到 Realm 前被赋值,由于Realm 在自己的引擎内部有很好的语义解释系统,所以 Objective?C 的许多属性特性将被忽略,如nonatomic, atomic, strong, copy 和 weak 等。 因此为了避免误解,官方推荐在编写数据模型的时候不要使用任何的属性特性。

1.2 使用RLMRealm对象, 保存指定模型

有3种写入方式,首先获取RLMRealm对象:RLMRealm *realm = [RLMRealm defaultRealm];

  • 写入方式1  :

//开启写入事务

[realm beginWriteTransaction];

//添加模型对象

[realm addObject:stu];

//提交写入事务

[realm commitWriteTransaction]; 

  • 写入方式2:

[realm transactionWithBlock:^{

        [realm addObject:stu];

    }];

  • 写入方式3:

[Stu createInRealm:realm withValue:@{@"stu_id": @22, @"name": @"马冬梅2", @"age": @666}];

 

1.3 使用RLMRealm对象, 更新指定模型

方式1:在事务中直接更新对象

[realm beginWriteTransaction];

stu.name = @"土豆";

[realm commitWriteTransaction];

方式2:根据主键进行更新

//1. 要求操作的模型, 必须实现方法+ (NSString *)primaryKey 返回主键
//2. 在事务中调用方法
[realm addOrUpdateObject:stu2];

方式3:根据主键进行更新
//1. 要求操作的模型, 必须实现方法+ (NSString *)primaryKey 返回主键
//2. 在事务中调用方法
[Stu createInRealm:realm withValue:@{@"stu_id": @22, @"name": @"马冬梅2", @"age": @666}];

 

1.4 使用RLMRealm对象, 删除数据

  • 删除指定的对象(在事务中)

[realm deleteObject:stu];
注意: 必须是从realm数据库中获取的模型对象, 而不是自己创建的
RLMObject *obj = [realm objectWithClassName:@"Stu" forPrimaryKey:@2];

  • 删除所有对象(在事务中)

[realm deleteAllObjects];

1.5 使用RLMRealm对象, 查询数据

  • 这里引出链式查询的概念:在查询结果的基础上, 进行二次查询,如下:

[stus objectsWhere:@"address beginswith ‘北京‘"];

  • 排序:

[stus sortedResultsUsingProperty:@"name" ascending:YES];

  • 分页:

注意:查询出来的结果对象是懒加载, 只有真正访问时, 才会加载相应对象, 所以, 这里的分页, 其实就是从所有集合中分页获取即可。代码演示:
RLMResults<Dog *> *dogs = [Dog allObjects];
for (NSInteger i = 0; i < 5; i++) {
Dog *dog = dogs[i];
// ...
}

  • 条件查询

RLMResults<Stu *> *stus = [Stu objectsWhere:@"name = ‘马冬梅‘"];
查询所有:[Stu allObjects];注意事项:
1. 所有的查询(包括查询和属性访问)在 Realm 中都是延迟加载的,只有当属性被访问时,才能够读取相应的数据
2. 查询结果并不是数据的拷贝:修改查询结果(在写入事务中)会直接修改硬盘上的数据。
3. 一旦检索执行之后, RLMResults 将随时保持更新

2.支持的数据类型

支持的类型包括:BOOL, bool, int, NSInteger, long, long long, float, double, NSString, NSDate, NSData, NSNumber。

缺点是不支持集合类型,其解决方案是 序列化成NSData进行存储  或者 转换成RLMArray<RLMObject>进行存储

 

3.关系

 

对一关系
     当一个对象持有另外一个对象时, 比如人有一个宠物??


对多关系

1. 在Dog中, 遵循指定协议方法
RLM_ARRAY_TYPE(Dog)
RLM_ARRAY_TYPE 宏创建了一个协议,从而允许 RLMArray<Dog> 语法的使用。
2. 在Person中, 定义属性
@property (nonatomic, strong) RLMArray<Dog *><Dog> *dogs;
注:虽然可以给 RLMArray 属性赋值为 nil,但是这仅用于“清空”数组,而不是用以移除数组。这意味着您总是可以向一个 RLMArray 属性中添加对象,即使其被置为了 nil。

反向关系

举例:人拥有狗, 狗又有相应的主人?
实现方法:
1. Dog中定义属性
@property (readonly) RLMLinkingObjects *master;
2. 实现协议方法, 标明链接关系
+ (NSDictionary<NSString *,RLMPropertyDescriptor *> *)linkingObjectsProperties {
return @{
@"master": [RLMPropertyDescriptor descriptorWithClass:NSClassFromString(@"Stu") propertyName:@"dogs"]
};
}

 

未完待续。。。

Realm数据库的简单介绍和使用