在13949次代码提交、6148个问题关闭之后:Realm 发布1.0版本,感谢大家的支持

2014年7月我们发布了 Realm —— 首个为移动端定制的数据库。今天,在13949次代码提交、6148个问题关闭之后,我们骄傲地宣布 Realm 1.0 版本发布。感谢广大 iOS 和 Andorid 开发社区对 Realm 的帮助。

起初,我们只为 iOS 和 Mac 开发者提供 Realm Objective-C,后来又添加了对 Swift 和 Android 的支持。最近还发布了支持 React Native 和 Xamarin 的版本。到目前为止,Realm 已经支持所有主流移动平台和开发语言。这次发布不仅体现了 Realm 两年的点滴积累,也得益于开发社区的大力支持。再次感谢开发社区!👏

在发布1.0版本之前,Realm 就已经被广大开发者社区所接受。Realm 的 GitHub 仓库总计获得了超过12000个星标(还在持续增加中)。Realm 正在被超过10万个活跃开发者使用,数万个 app 由 Realm 提供数据库支持。这包括许多大型的公司例如星巴克、Twitter、 Anheuser-Busch、NBCUniversal、阿里巴巴、 eBay 等等。Realm 帮助开发者更便捷地提供更好的用户体验,从而创造出更好的 app。1.0版本的发布更是让开发者相信 Realm 进入了一个更成熟和稳定的阶段。

我们的修改记录 Java Objective-C 和 Swift 保存了这两年期间大大小小的改动。

什么是 Realm?

Realm 不是 ORM,也不基于 SQLite 创建,而是为移动开发者定制的全功能数据库。它可以将原生对象直接映射到我们开发的数据库引擎(远不仅是一个键值对存储)中。你可以使用 Realm 存储复杂的对象、操作对象间的关系,还可以进行高级的查询。

// Define you model class by extending RealmObject
public class Dog extends RealmObject {
    private String name;
    private int age;

    // ... Generated getters and setters ...
}

public class Person extends RealmObject {
    @PrimaryKey
    private long id;
    private String name;
    private RealmList<Dog> dogs; // Declare one-to-many relationships

    public Person(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // ... Generated getters and setters ...
}

// Use them like regular java objects
Dog dog = new Dog();
dog.setName("Rex");
dog.setAge(1);

// Create a RealmConfiguration that saves the Realm file in the app's "files" directory.
RealmConfiguration realmConfig = new RealmConfiguration.Builder(context).build();
Realm.setDefaultConfiguration(realmConfig);

// Get a Realm instance for this thread
Realm realm = Realm.getDefaultInstance();

// Query Realm for all dogs younger than 2 years old
final RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
puppies.size(); // => 0 because no dogs have been added to the Realm yet

// Persist your data in a transaction
realm.beginTransaction();
final Dog managedDog = realm.copyToRealm(dog); // Persist unmanaged objects
Person person = realm.createObject(Person.class); // Create managed objects directly
person.getDogs().add(managedDog);
realm.commitTransaction();

// Listeners will be notified when data changes
puppies.addChangeListener(new RealmChangeListener<RealmResults<Dog>>() {
    @Override
    public void onChange(RealmResults<Dog> results) {
        // Query results are updated in real time
        puppies.size(); // => 1
    }
});

// Asynchronously update objects on a background thread
realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm bgRealm) {
        Dog dog = bgRealm.where(Dog.class).equals("age", 1).findFirst();
        dog.setAge(3);
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() {
      // Original queries and Realm objects are automatically updated.
      puppies.size(); // => 0 because there are no more puppies younger than 2 years old
      managedDog.getAge();   // => 3 the dogs age is updated
    }
});
// Define your models like regular Objective‑C classes
@interface Dog : RLMObject
@property NSString *name;
@property NSData   *picture;
@property NSInteger age;
@end
@implementation Dog
@end
RLM_ARRAY_TYPE(Dog)
@interface Person : RLMObject
@property NSString             *name;
@property RLMArray<Dog *><Dog> *dogs;
@end
@implementation Person
@end

// Use them like regular Objective‑C objects
Dog *mydog = [[Dog alloc] init];
mydog.name = @"Rex";
mydog.age = 1;
mydog.picture = nil; // properties are nullable
NSLog(@"Name of dog: %@", mydog.name);

// Query Realm for all dogs less than 2 years old
RLMResults<Dog *> *puppies = [Dog objectsWhere:@"age < 2"];
puppies.count; // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
  [realm addObject:mydog];
}];

// Queries are updated in real-time
puppies.count; // => 1

// Query and update the result in another thread
dispatch_async(dispatch_queue_create("background", 0), ^{
  Dog *theDog = [[Dog objectsWhere:@"age == 1"] firstObject];
  RLMRealm *realm = [RLMRealm defaultRealm];
  [realm beginWriteTransaction];
  theDog.age = 3;
  [realm commitWriteTransaction];
});
// Define your models like regular Swift classes
class Dog: Object {
  dynamic var name = ""
  dynamic var age = 0
}
class Person: Object {
  dynamic var name = ""
  dynamic var picture: NSData? = nil // optionals supported
  let dogs = List<Dog>()
}

// Use them like regular Swift objects
let myDog = Dog()
myDog.name = "Rex"
myDog.age = 1
print("name of dog: \(myDog.name)")

// Get the default Realm
let realm = try! Realm()

// Query Realm for all dogs less than 2 years old
let puppies = realm.objects(Dog).filter("age < 2")
puppies.count // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
try! realm.write {
  realm.add(myDog)
}

// Queries are updated in real-time
puppies.count // => 1

// Query and update from any thread
dispatch_async(dispatch_queue_create("background", nil)) {
  let realm = try! Realm()
  let theDog = realm.objects(Dog).filter("age == 1").first
  try! realm.write {
    theDog!.age = 3
  }
}
// Define your models and their properties
class Car {}
Car.schema = {
  name: 'Car',
  properties: {
    make:  'string',
    model: 'string',
    miles: 'int',
  }
};
class Person {}
Person.schema = {
  name: 'Person',
  properties: {
    name:    {type: 'string'},
    cars:    {type: 'list', objectType: 'Car'},
    picture: {type: 'data', optional: true}, // optional property
  }
};

// Get the default Realm with support for our objects
let realm = new Realm({schema: [Car, Person]});

// Create Realm objects and write to local storage
realm.write(() => {
  let myCar = realm.create('Car', {
    make: 'Honda',
    model: 'Civic',
    miles: 1000,
  });
  myCar.miles += 20; // Update a property value
});

// Query Realm for all cars with a high mileage
let cars = realm.objects('Car').filtered('miles > 1000');

// Will return a Results object with our 1 car
cars.length // => 1

// Add another car
realm.write(() => {
  let myCar = realm.create('Car', {
    make: 'Ford',
    model: 'Focus',
    miles: 2000,
  });

// Query results are updated in real-time
cars.length // => 2
// Define your models like regular C# classes
public class Dog : RealmObject 
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Owner { get; set; }
}

public class Person : RealmObject 
{
    public string Name { get; set; }
    public RealmList<Dog> Dogs { get; } 
}

var realm = Realm.GetInstance();

// Use LINQ to query
var puppies = realm.All<Dog>().Where(d => d.Age < 2);

puppies.Count(); // => 0 because no dogs have been added yet

// Update and persist objects with a thread-safe transaction
realm.Write(() => 
{
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Rex";
    mydog.Age = 1;
});

// Queries are updated in real-time
puppies.Count(); // => 1

// LINQ query syntax works as well
var oldDogs = from d in realm.All<Dog>() where d.Age > 8 select d;

// Query and update from any thread
new Thread(() =>
{
    var realm2 = Realm.GetInstance();

    var theDog = realm2.All<Dog>().Where(d => d.Age == 1).First();
    realm2.Write(() => theDog.Age = 3);
}).Start();

Get more development news like this

为什么使用 Realm?

简单

易用性是 Realm 的主要目标。开发者反馈说他们只用花费数小时就将大型应用的数据存储迁移到了 Realm。一般来说,Realm 能在实现、优化和调试上节约数周时间。

快速

Realm 的易用性并不以牺牲性能为代价。我们的引擎通过使用内存映射(memory mapping)、懒加载(lazy loading)使得其访问速度优于 SQLite。尽管数据库性能比较往往根据实际情况而有所差异,但仍有很多开发者反馈 Realm 带来了巨大的性能提升。

跨平台

Realm 支持 JavaObjective-CReact NativeSwiftXamarin。你可以在不同平台访问同一个 Realm 文件,使用相同的数据模型定义,编写相似的业务逻辑。你更可以使用 Realm Browser 来打开 Realm 文件进行调试。

高级特性

Realm 对象永远与底层数据保持同步,这种机制很适合响应式编程和无方向的数据流。你可以在多个 Realm 对象间建立关系、使用高级的查询、信赖内置的 AES256 数据加密,以及为集成 Realm 数据与 UI 控件而开发的各种扩展。

信任

在大型 app 中使用 Realm?用户量很大?没问题,Realm 已经在生产环境中使用了很长一段时间。这其中包括一些大型的银行、健康顾问提供商和复杂的企业应用。同时还有许多 Apple App Store 和 Google Play Store 中的热门应用在使用 Realm。

社区驱动

Realm 是 GitHub 上的开源项目,需求往往来自社区反馈,并且我们十分欢迎贡���代码。GitHub 上的12000多个星标、数百个基于 Realm 的 app 和各种组件,使用 Realm 的时候,你永远不会觉得孤单。

支持

技术支持和 Bug 修正永远是 Realm 工程师的首要任务。你可以通过 Stack Overflow 得到来自 Realm 工程师的答案。

谁在使用 Realm?

亿万人在使用基于 Realm 的 app。

Twitter

最流行的 app 信任 Realm。Twitter 的创新视频应用 Vine 和它的2亿用户从2016年开始使用 Realm。

星巴克

这家财富500强中的零售商在它的旗舰 app 中使用 Realm,使你更方便地得到中意的饮品。

阿里巴巴

这家纽约证券交易所上市的中国巨无霸公司在他的 B2B 应用中使用 Realm。去年供应商和采购方在其平台上的交易创造了30亿美元的利润。

百威

这家巨型啤酒厂在他们的 TapWiser 应用中使用 Realm。酒吧和商店可以快速地通过手机订货而不需使用电脑。

SAP

如果你是 Concur 的用户,那么你已经在使用 Realm 了。这个拥有2万客户的应用给3千万员工提供财务报销服务。

Rite Aid

这个美国的财富500强零售业巨头在它的 EnvisionRx 应用中使用 Realm, 以帮助消费者们安全地存储数据。

Realm 的用户还包括:亚马逊、eBay、谷歌、GoPro、沃尔玛、阿迪达斯、思科、NBCUniversal、耐克、NFL等等。

接下来

如果你需要帮助请在 StackOverflow 上提问。

关注我们的微博获得最新的中文讯息。

开始使用 Realm Java - GitHub 项目页面
开始使用 Realm Objective-C - GitHub 项目页面
开始使用 Realm Swift - GitHub 项目页面
开始使用 Realm React Native - GitHub 项目页面
开始使用 Realm Xamarin - GitHub 项目页面

我们等不及想看看大家都能用 Realm 创造出什么!