realm or: how i learned to stop worrying and love my app database
TRANSCRIPT
RealmHow I
Learned to Stop
Worrying and
Love my App
Database
or
Sergi MartínezAndroid Developer at Schibsted Spain
Android GDE@sergiandreplace
The usual stuffMy big server
My big database
My mobile app
My little databas
e
My nice
API
The internet!
The usual stuffMy big server
My big database
My mobile app
My little databas
e
My nice
API
The internet!
This tries to mimic this
The usual stuffMy big server
My big database
My mobile app
My little databas
e
My nice
API
The internet!
Here We only need to cache entities
The initial solutionSQLite
SQLiteSQL languageRelationshipsNon-java data typesSQL QueriesSQL stuff
SQLiteSQL languageRelationshipsNon-java data typesSQL QueriesSQL stuff
Do we need these?
SQLiteSQL languageRelationshipsNon-java data typesSQL QueriesSQL stuff
Do we need these? Really?
Also...SQLDbHelperSQL QueriesContent ProvidersLoadersetc
Also...SQLDbHelperSQL QueriesContent ProvidersLoadersetc
Boilerplate
Also...SQLDbHelperSQL QueriesContent ProvidersLoadersetc
Boilerplate
Boilerplate
Also...SQLDbHelperSQL QueriesContent ProvidersLoadersetc
Boilerplate
Boilerplate
OH! Wow! So much boilerplate
Also...SQLDbHelperSQL QueriesContent ProvidersLoadersetc
Boilerplate
Boilerplate
OH! Wow! So much boilerplate
“Hard” to create. Excessive coupling with UI
Also...SQLDbHelperSQL QueriesContent ProvidersLoadersetc
Boilerplate
Boilerplate
OH! Wow! So much boilerplate
“Hard” to create. Excessive coupling with UI
Probably… more boilerplate
Let’s try something different… RealmIt stores objectsHierarchical relationships (sort of)No boilerplate (just probably mappers)Fast!Reduces dev time drastically
Adding Realm to your projectYour project build.gradlebuildscript { repositories { jcenter() } dependencies { classpath "io.realm:realm-gradle-plugin:0.89.0" }}
apply plugin: 'realm-android'
Your app build.gradle
Realm Objectspublic class Minion extends RealmObject {
private String name; private int eyes; private boolean goggles;
public String getName() { return name; } public void setName(String name) { this.name = name; }
public int getEyes() { return eyes; } public void setEyes(int eyes) { this.eyes = eyes; }
public boolean hasGoggles() { return goggles; } public void setGoggles(boolean goggles) { this.goggles = goggles; }}
Realm Objectspublic class Minion extends RealmObject {
private String name; private int eyes; private boolean goggles;
public String getName() { return name; } public void setName(String name) { this.name = name; }
public int getEyes() { return eyes; } public void setEyes(int eyes) { this.eyes = eyes; }
public boolean hasGoggles() { return goggles; } public void setGoggles(boolean goggles) { this.goggles = goggles; }}
Must extend RealmObject
Realm Objectspublic class Minion extends RealmObject {
private String name; private int eyes; private boolean goggles;
public String getName() { return name; } public void setName(String name) { this.name = name; }
public int getEyes() { return eyes; } public void setEyes(int eyes) { this.eyes = eyes; }
public boolean hasGoggles() { return goggles; } public void setGoggles(boolean goggles) { this.goggles = goggles; }}
Must extend RealmObjectNot exactly true since last thursday (#$%@!). More later...
Realm Objectspublic class Minion extends RealmObject {
private String name; private int eyes; private boolean goggles;
public String getName() { return name; } public void setName(String name) { this.name = name; }
public int getEyes() { return eyes; } public void setEyes(int eyes) { this.eyes = eyes; }
public boolean hasGoggles() { return goggles; } public void setGoggles(boolean goggles) { this.goggles = goggles; }}
Object members that will be storedMore on types later
Realm Objectspublic class Minion extends RealmObject {
private String name; private int eyes; private boolean goggles;
public String getName() { return name; } public void setName(String name) { this.name = name; }
public int getEyes() { return eyes; } public void setEyes(int eyes) { this.eyes = eyes; }
public boolean hasGoggles() { return goggles; } public void setGoggles(boolean goggles) { this.goggles = goggles; }}
Usual getters and setters
Supported data typesboolean/Booleanbyte/Byteshort/Shortint/Integerlong/Long
float/Floatdouble/DoubleStringDateByte[]
Storing an objectrealm.beginTransaction();Minion minion = realm.createObject(Minion.class);minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);realm.commitTransaction();
realm.cancelTransaction();
or
First, we start a transaction
Storing an objectrealm.beginTransaction();Minion minion = realm.createObject(Minion.class);minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);realm.commitTransaction();
realm.cancelTransaction();
or
Then we create an instance inside our realm
Storing an objectrealm.beginTransaction();Minion minion = realm.createObject(Minion.class);minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);realm.commitTransaction();
realm.cancelTransaction();
or
We set the values
Storing an objectrealm.beginTransaction();Minion minion = realm.createObject(Minion.class);minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);realm.commitTransaction();
realm.cancelTransaction();
or
And commit the transaction. Then, our changes are saved
Storing an objectrealm.beginTransaction();Minion minion = realm.createObject(Minion.class);minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);realm.commitTransaction();
realm.cancelTransaction();
or
Or we cancel the transaction and the new object is discarded
Storing an object - IIMinion minion = new Minion();minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);
realm.beginTransaction();realm.copyToRealm(minion);realm.commitTransaction();
Another way. We create the object outside the realm
Storing an object - IIMinion minion = new Minion();minion.setName("Bob");minion.setEyes(1);minion.setGoggles(true);
realm.beginTransaction();realm.copyToRealm(minion);realm.commitTransaction();
Then, we begin a transaction, copy the object into the realm, and commit
Obtaining your RealmFirst, create your Realm configurationRealmConfiguration config = new RealmConfiguration.Builder(context) .name("myrealm.realm") .encryptionKey(getKey()) .schemaVersion(42) .setModules(new MySchemaModule()) .migration(new MyMigration()) .build();
Obtaining your RealmThen, get an instanceRealmConfiguration config = new RealmConfiguration.Builder(context) .name("myrealm.realm") .encryptionKey(getKey()) .schemaVersion(42) .setModules(new MySchemaModule()) .migration(new MyMigration()) .build();
Realm myRealm = Realm.getInstance(config);
Obtaining your RealmOr use the default Realm InstanceRealmConfiguration config = new RealmConfiguration.Builder(context) .name("myrealm.realm") .encryptionKey(getKey()) .schemaVersion(42) .setModules(new MySchemaModule()) .migration(new MyMigration()) .build();
Realm.setDefaultConfiguration(config);
And obtain it anywhere Realm realm = Realm.getDefaultInstance(); // Stuff realm.close();
Close your RealmsFor each
Realm.getDefaultInstance()
or
Realm.getInstance()
you must execute realm.close() at the end
Querying a RealmRealm uses fluent syntax. Just create a RealmQuery object based on the Realm class you wantRealmQuery<Minion> query = realm.where(Minion.class);
Add operations and filters and executeRealmResults<Minion> results = query.equalTo(“name”, “Bob”).findAll();
Do something with the resultfor (Minion minion:results) {…. //Do stuff}
Query operatorsbetween()greaterThan()lessThan()greaterThanOrEqual()lessThanOrEqual()
equalTo()notEqualTo()contains()beginsWith()endsWith()
Annotations@Index
@PrimaryKey
@Ignore
@Required
Relationships - 1:NJust have a RealmObject with a RealmObjectpublic class Minion extends RealmObject { private String name; private int eyes; private boolean goggles; private Banana banana
//Getters, setters and so on
}
Public class Banana extends RealmObject { …}
Storing 1:N related objectsrealm.beginTransaction()
Banana banana = realm.createObject(Banana.class);banana.setSomething…
Minion minion = realm.createObject(Minion.class);minion.setName(“Bob”);minion.setBanana(banana);
realm.writeTransaction();
Relationships - M:NJust have a RealmObject with a List<? extends RealmObject>public class Minion extends RealmObject { private String name; private int eyes; private boolean goggles; private RealmList<Banana> bananas
//Getters, setters and so on
}
Public class Banana extends RealmObject { …}
Storing M:N related objectsrealm.beginTransaction()
Banana banana = realm.createObject(Banana.class);banana.setSomething…
Minion minion = realm.createObject(Minion.class);minion.setName(“Bob”);minion.getBananas().add(banana);
realm.writeTransaction();
Querying M:N related objectsRealmResults<Minion> minions = realm.where(Minions.class) .equalTo("banana.size", "big") .findAll();
ThreadingEach Realm should live in the same Thread is has been created
You can’t pass Realms between threads
Realms are automatically updated between threads IF they are in threads with a Looper
Otherwise… Realm.refresh()
More thingsDynamic realms
Schemas
Migrations
UI controls
Browsers
etc...
Brand new changesThis week on Realm:
RealmModel interface + static methods
RealmCollection/RealmOrderedCollection Interfaces
Primary keys can be null!
How I use itpublic abstract class VOBaseMapper<V extends RealmObject,E> {
public abstract V toVO(E entity); public abstract E toEntity(V vo) ;
public RealmList<V> toVO(List<E> entities) { RealmList<V> realmList=new RealmList<V>(); for (E entity:entities) { realmList.add(toVO(entity)); } return realmList; }
How I use it public List<E> toEntity(RealmList<V> vos) { List<E> applicationEntityList = new ArrayList<>(); for(V vo :vos){ applicationEntityList.add(toEntity(vo)); } return applicationEntityList; }
public List<E> toEntity(RealmResults<V> vos) { List<E> applicationEntityList = new ArrayList<>(); for(V vo :vos){ applicationEntityList.add(toEntity(vo)); } return applicationEntityList; }}
How I use itpublic class UserVOMapper extends VOBaseMapper<UserVO,User > {
private User user;
@Override public UserVO toVO(User user) { UserVO vo=new UserVO(); vo.setName(user.name); vo.setEmail(user.email); return vo; }
@Override public User toEntity(UserVO vo) { User user= new User(); user.name=vo.getName(); user.email=vo.getEmail(); return user; }}
And that’s not allBut enough for today.Questions?
@sergiandreplace
Thanks for coming