KEMBAR78
RealmDB for Android | PPTX
RealmDB. Fast & Simple
by Anton Minashkin
Whats wrong with SQLite + ORM?
● Boilerplate code
● SQL is ugly and hard to learn
● DTO <-> ORM
● Threads
Realm is a mobile
database
Realm is a replacement for SQLite & Core Data.
It can save you thousands of lines of code & weeks of work,
and lets you craft amazing new user experiences.
Realm is…
blah-blah-blah…
...fast and simple data
storage
...and cute ^_^
History
● Comes from YCombinator
● TightDB -> Realm
● In development since 2011
● 2nd-most deployed DB in the world (proof?)
Fast
Fast
Fast
Why so fast?
● zero-copy architecture
● bitpacking reduces memory usage by up to
90%
● caching & vectorization makes access faster
then native C
● built from scratch, based on C++ core
● proxy
Models
Field types: boolean, short, ìnt, long, float, double,
String, Date and byte[]
Annotations: @Ignore, @Index, @PrimaryKey
Models
public class User extends RealmObject {
@PrimaryKey
private String name;
private int age;
@Ignore
private int sessionId;
// Standard getters & setters generated by your IDE…
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public int getSessionId() { return sessionId; }
public void setSessionId(int dontPersist) { this.sessionId = sessionId; }
}
Writes
● Always use Transactions
● Writes block each other
● Use Realm.copyToRealm()
● Read & Writes are ACID
Creating objects
realm.beginTransaction();
User user = realm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();
Creating objects
User user = new User("John");
user.setEmail("john@corporation.com");
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();
Transaction blocks
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
}
});
Queries
// Build the query looking at all users:
RealmQuery<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");
// Execute the query:
RealmResults<User> result1 = query.findAll();
Queries
RealmResults<User> result = realm.where(User.class)
.equalTo("name", "John")
.or()
.equalTo("name", "Peter")
.findAll();
Retrieving objects by type
Realm.allObjects(java.lang.Class<E> clazz)
Realm.allObjectsSorted(...)
Conditions
● between, greaterThan(), lessThan(), greaterThanOrEqualTo() &
lessThanOrEqualTo()
● equalTo() & notEqualTo()
● contains(), beginsWith() & endsWith()
Modifiers
String conditions can ignore case for characters
A-Z and a-z by using the CASE_INSENSITIVE
modifier.
Implicit Logical Operators
RealmResults<User> r = realm.where(User.class)
.greaterThan("age", 10) //AND
.beginGroup()
.equalTo("name", "Peter")
.or()
.contains("name", "Jo")
.endGroup()
.findAll();
Sorting
RealmResults<User> result = realm.where(User.class).findAll();
result.sort("age"); // Sort ascending
result.sort("age", RealmResults.SORT_ORDER_DESCENDING);
Chaining Queries
RealmResults<User> teenagers = realm.where(User.class)
.between("age", 13, 20).findAll();
RealmResults<User> firstJohn = teenagers.where().equalTo("name",
"John").findFirst();
Aggregation
long sum = result.sum("age").longValue();
long min = result.min("age").longValue();
long max = result.max("age").longValue();
double average = result.average("age");
long matches = result.size();
Iterations
for (User u : result) {
// ... do something with the object ...
}
for (int i = 0; i < result.size(); i++) {
User u = result.get(i);
// ... do something with the object ...
}
Deletion
// All changes to data must happen in a transaction
realm.beginTransaction();
// remove single match
result.remove(0);
result.removeLast();
// remove a single object
Dog dog = result.get(5);
dog.removeFromRealm();
// Delete all matches
result.clear();
realm.commitTransaction()
Realms
Realm == Database
The Default Realm
Realm.getInstance(Context context)
Mapped to: default.realm
Located in: Context.getFilesDir() --/data/data/files/
Check location: realm.getPath()
Other Realms
Realm realm = Realm.getInstance(this, "mycustom.realm");
Using a Realm across Threads
Realm, RealmObject or RealmResults instances cannot be passed across
threads!
Wanna same objects in other thread? Requery!
Closing Realm instances
Realm implements Closeable
Realm instances are reference counted
For the UI thread the easiest way is to execute realm.close() in the
onDestroy() method.
Auto-Refresh
If a thread is associated with Looper (e.g. UI thread) then Realm has
AutoRefresh feature;
Check it: Realm.isAutoRefresh()
Relationships
public class Email extends RealmObject {
private String address;
private boolean active;
// ... setters and getters left out
}
public class Contact extends RealmObject {
private String name;
private Email email;
// ... setters and getters left out
}
Relationships
public class Contact extends RealmObject {
private RealmList<Email> emails;
// Other fields…
}
RealmResults<Contact> contacts = realm
.where(Contact.class)
.equalTo("email.active", true).findAll();
JSON
Object should be represented as: String, JSONObject, InputStream
// Insert from a string
realm.beginTransaction();
realm.createObjectFromJson(City.class, "{ city: "Copenhagen",
id: 1 }");
realm.commitTransaction();
JSON
// Insert multiple items using a InputStream
InputStream is = new FileInputStream(new File("path_to_file"));
realm.beginTransaction();
try {
realm.createAllFromJson(City.class, is);
realm.commitTransaction();
} catch (IOException e) {
realm.cancelTransaction();
}
Notifications
realm.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
// ... do something with the updates (UI, etc.) ...
}
});
…
realm.removeAllChangeListeners();
Migrations
Migrations are a work in progress. The feature is fully functional, but the current
interface is cumbersome, and will be rewritten soon.
Encryption
Please take note of the Export Compliance section of our LICENSE, as it
places restrictions against the usage of Realm if you are located in countries
with an export restriction or embargo from the United States.
Encryption
byte[] key = new byte[32];
new SecureRandom().nextBytes(key);
Realm realm = Realm.create(this, key);
// ... use the Realm as normal ...
Encryption
Using Encryption requires building Realm from source:
1. Follow the normal build instructions, but before running ./gradlew
assemble, add the lineencryption=true to local.properties.
2. After building Realm, replace the copy of realm-<VERSION>.aar in your
project with the one found at realm/build/outputs/aar/realm-
<VERSION>.aar.
Adapter
public class MyAdapter extends RealmBaseAdapter<TimeStamp>
implements ListAdapter {
…
@Override
public View getView(int position, View convertView,
ViewGroup parent) {...}
}
Realm Browser
Realm Browser
Only available on Mac OS X at the moment! We are working on Windows &
Linux versions.
Example
Code time!
Current limitations (still beta)
General:
1. The upper limit of class names is 57 characters. Realm for Android prepend class_ to all names,
and the browser will show it as part of the name.
2. The length of field names has a upper limit of 63 character.
3. The dates are truncated with a precision of one second. In order to maintain compability
between 32 bits and 64 bits devices, it is not possible to store dates before 1900-12-13 and after
2038-01-19.
Current limitations (still beta)
General:
4. Nested transactions are not supported, and an exception is throw if it is detected.
5. Strings and byte arrays (byte[]) cannot be larger than 16 MB.
6. Case insensitive string matches in queries are only supported for character sets in ‘Latin Basic’,
‘Latin Supplement’, ‘Latin Extended A’, ‘Latin Extended B’ (UTF-8 range 0-591).
Current limitations (still beta)
Sorting
Sorting is currently limited to character sets in ‘Latin Basic’, ‘Latin Supplement’, ‘Latin Extended A’,
‘Latin Extended B’ (UTF-8 range 0-591). For other charsets, sorting will not change the RealmResults
object.
Current limitations (still beta)
Threads
Although Realm files can be accessed by multiple threads concurrently, you cannot hand over
Realms, Realm objects, queries, and results between threads. Moreover, asynchronous queries are
currently not supported.
Current limitations (still beta)
null values
It is not possible to store null as a value for primitive data types (booleans, integers, floating-point
numbers, dates, and strings). Supporting null is under active development but until fully supported, we
suggest that you add an extra boolean field to capture if a field is null or not.
Current limitations (still beta)
Realm files cannot be accessed by concurrent processes
Although Realm files can be accessed by multiple threads concurrently, they can only be accessed by
a single process at a time. Different processes should either copy Realm files or create their own.
Multi-process support is coming soon.
Questions?
Thanks =)
http://realm.io/
http://realm.io/docs/java/0.80.0/
@Twitter: AntonMinashkin
Email: anton.minashkin@outlook.com

RealmDB for Android

  • 1.
    RealmDB. Fast &Simple by Anton Minashkin
  • 2.
    Whats wrong withSQLite + ORM? ● Boilerplate code ● SQL is ugly and hard to learn ● DTO <-> ORM ● Threads
  • 3.
    Realm is amobile database Realm is a replacement for SQLite & Core Data. It can save you thousands of lines of code & weeks of work, and lets you craft amazing new user experiences.
  • 4.
    Realm is… blah-blah-blah… ...fast andsimple data storage ...and cute ^_^
  • 5.
    History ● Comes fromYCombinator ● TightDB -> Realm ● In development since 2011 ● 2nd-most deployed DB in the world (proof?)
  • 6.
  • 7.
  • 8.
  • 9.
    Why so fast? ●zero-copy architecture ● bitpacking reduces memory usage by up to 90% ● caching & vectorization makes access faster then native C ● built from scratch, based on C++ core ● proxy
  • 10.
    Models Field types: boolean,short, ìnt, long, float, double, String, Date and byte[] Annotations: @Ignore, @Index, @PrimaryKey
  • 11.
    Models public class Userextends RealmObject { @PrimaryKey private String name; private int age; @Ignore private int sessionId; // Standard getters & setters generated by your IDE… public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSessionId() { return sessionId; } public void setSessionId(int dontPersist) { this.sessionId = sessionId; } }
  • 12.
    Writes ● Always useTransactions ● Writes block each other ● Use Realm.copyToRealm() ● Read & Writes are ACID
  • 13.
    Creating objects realm.beginTransaction(); User user= realm.createObject(User.class); user.setName("John"); user.setEmail("john@corporation.com"); realm.commitTransaction();
  • 14.
    Creating objects User user= new User("John"); user.setEmail("john@corporation.com"); realm.beginTransaction(); User realmUser = realm.copyToRealm(user); realm.commitTransaction();
  • 15.
    Transaction blocks realm.executeTransaction(new Realm.Transaction(){ @Override public void execute(Realm realm) { User user = realm.createObject(User.class); user.setName("John"); user.setEmail("john@corporation.com"); } });
  • 16.
    Queries // Build thequery looking at all users: RealmQuery<User> query = realm.where(User.class); // Add query conditions: query.equalTo("name", "John"); query.or().equalTo("name", "Peter"); // Execute the query: RealmResults<User> result1 = query.findAll();
  • 17.
    Queries RealmResults<User> result =realm.where(User.class) .equalTo("name", "John") .or() .equalTo("name", "Peter") .findAll();
  • 18.
    Retrieving objects bytype Realm.allObjects(java.lang.Class<E> clazz) Realm.allObjectsSorted(...)
  • 19.
    Conditions ● between, greaterThan(),lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo() ● equalTo() & notEqualTo() ● contains(), beginsWith() & endsWith()
  • 20.
    Modifiers String conditions canignore case for characters A-Z and a-z by using the CASE_INSENSITIVE modifier.
  • 21.
    Implicit Logical Operators RealmResults<User>r = realm.where(User.class) .greaterThan("age", 10) //AND .beginGroup() .equalTo("name", "Peter") .or() .contains("name", "Jo") .endGroup() .findAll();
  • 22.
    Sorting RealmResults<User> result =realm.where(User.class).findAll(); result.sort("age"); // Sort ascending result.sort("age", RealmResults.SORT_ORDER_DESCENDING);
  • 23.
    Chaining Queries RealmResults<User> teenagers= realm.where(User.class) .between("age", 13, 20).findAll(); RealmResults<User> firstJohn = teenagers.where().equalTo("name", "John").findFirst();
  • 24.
    Aggregation long sum =result.sum("age").longValue(); long min = result.min("age").longValue(); long max = result.max("age").longValue(); double average = result.average("age"); long matches = result.size();
  • 25.
    Iterations for (User u: result) { // ... do something with the object ... } for (int i = 0; i < result.size(); i++) { User u = result.get(i); // ... do something with the object ... }
  • 26.
    Deletion // All changesto data must happen in a transaction realm.beginTransaction(); // remove single match result.remove(0); result.removeLast(); // remove a single object Dog dog = result.get(5); dog.removeFromRealm(); // Delete all matches result.clear(); realm.commitTransaction()
  • 27.
  • 28.
    The Default Realm Realm.getInstance(Contextcontext) Mapped to: default.realm Located in: Context.getFilesDir() --/data/data/files/ Check location: realm.getPath()
  • 29.
    Other Realms Realm realm= Realm.getInstance(this, "mycustom.realm");
  • 30.
    Using a Realmacross Threads Realm, RealmObject or RealmResults instances cannot be passed across threads! Wanna same objects in other thread? Requery!
  • 31.
    Closing Realm instances Realmimplements Closeable Realm instances are reference counted For the UI thread the easiest way is to execute realm.close() in the onDestroy() method.
  • 32.
    Auto-Refresh If a threadis associated with Looper (e.g. UI thread) then Realm has AutoRefresh feature; Check it: Realm.isAutoRefresh()
  • 33.
    Relationships public class Emailextends RealmObject { private String address; private boolean active; // ... setters and getters left out } public class Contact extends RealmObject { private String name; private Email email; // ... setters and getters left out }
  • 34.
    Relationships public class Contactextends RealmObject { private RealmList<Email> emails; // Other fields… } RealmResults<Contact> contacts = realm .where(Contact.class) .equalTo("email.active", true).findAll();
  • 35.
    JSON Object should berepresented as: String, JSONObject, InputStream // Insert from a string realm.beginTransaction(); realm.createObjectFromJson(City.class, "{ city: "Copenhagen", id: 1 }"); realm.commitTransaction();
  • 36.
    JSON // Insert multipleitems using a InputStream InputStream is = new FileInputStream(new File("path_to_file")); realm.beginTransaction(); try { realm.createAllFromJson(City.class, is); realm.commitTransaction(); } catch (IOException e) { realm.cancelTransaction(); }
  • 37.
    Notifications realm.addChangeListener(new RealmChangeListener() { @Override publicvoid onChange() { // ... do something with the updates (UI, etc.) ... } }); … realm.removeAllChangeListeners();
  • 38.
    Migrations Migrations are awork in progress. The feature is fully functional, but the current interface is cumbersome, and will be rewritten soon.
  • 39.
    Encryption Please take noteof the Export Compliance section of our LICENSE, as it places restrictions against the usage of Realm if you are located in countries with an export restriction or embargo from the United States.
  • 40.
    Encryption byte[] key =new byte[32]; new SecureRandom().nextBytes(key); Realm realm = Realm.create(this, key); // ... use the Realm as normal ...
  • 41.
    Encryption Using Encryption requiresbuilding Realm from source: 1. Follow the normal build instructions, but before running ./gradlew assemble, add the lineencryption=true to local.properties. 2. After building Realm, replace the copy of realm-<VERSION>.aar in your project with the one found at realm/build/outputs/aar/realm- <VERSION>.aar.
  • 42.
    Adapter public class MyAdapterextends RealmBaseAdapter<TimeStamp> implements ListAdapter { … @Override public View getView(int position, View convertView, ViewGroup parent) {...} }
  • 43.
  • 44.
    Realm Browser Only availableon Mac OS X at the moment! We are working on Windows & Linux versions.
  • 45.
  • 46.
    Current limitations (stillbeta) General: 1. The upper limit of class names is 57 characters. Realm for Android prepend class_ to all names, and the browser will show it as part of the name. 2. The length of field names has a upper limit of 63 character. 3. The dates are truncated with a precision of one second. In order to maintain compability between 32 bits and 64 bits devices, it is not possible to store dates before 1900-12-13 and after 2038-01-19.
  • 47.
    Current limitations (stillbeta) General: 4. Nested transactions are not supported, and an exception is throw if it is detected. 5. Strings and byte arrays (byte[]) cannot be larger than 16 MB. 6. Case insensitive string matches in queries are only supported for character sets in ‘Latin Basic’, ‘Latin Supplement’, ‘Latin Extended A’, ‘Latin Extended B’ (UTF-8 range 0-591).
  • 48.
    Current limitations (stillbeta) Sorting Sorting is currently limited to character sets in ‘Latin Basic’, ‘Latin Supplement’, ‘Latin Extended A’, ‘Latin Extended B’ (UTF-8 range 0-591). For other charsets, sorting will not change the RealmResults object.
  • 49.
    Current limitations (stillbeta) Threads Although Realm files can be accessed by multiple threads concurrently, you cannot hand over Realms, Realm objects, queries, and results between threads. Moreover, asynchronous queries are currently not supported.
  • 50.
    Current limitations (stillbeta) null values It is not possible to store null as a value for primitive data types (booleans, integers, floating-point numbers, dates, and strings). Supporting null is under active development but until fully supported, we suggest that you add an extra boolean field to capture if a field is null or not.
  • 51.
    Current limitations (stillbeta) Realm files cannot be accessed by concurrent processes Although Realm files can be accessed by multiple threads concurrently, they can only be accessed by a single process at a time. Different processes should either copy Realm files or create their own. Multi-process support is coming soon.
  • 52.
  • 53.