Share
Embed
Persistência com Realm.io
Talk do Meetup #02 do RJ da comunidade Android.
Pedro Salomão
September 30, 2015
Transcript
36 slides
-
Persistência O que é persistência? Quando devemos buscar uma biblioteca?
Realm resolve todos os problemas de persistência? Existe bala de prata? -
buildscript { repositories {
jcenter() } } dependencies { compile 'io.realm:realm-‐android:0.82.2' } ../your_module/build.gradle -‐keep class io.realm.annotations.RealmModule -‐keep @io.realm.annotations.RealmModule class * -‐dontwarn javax.** -‐dontwarn io.realm.** ../your_module/proguard-‐rules.pro -
Modelo public class User extends RealmObject { private String name;
private boolean boolValue; private short number; private int number2; private long number3; private float fractionNumber; private double fractionNumber2; private byte[] bytes; private Date date; private RealmObject object; private RealmList<? extends RealmObject> list; @PrimaryKey private int id; // inteiros ou String @Index private int index; // Tipos primitivos @Ignore private int sessionId; // Getters & Setters padrão public String getName() { return name; } public void setName(String name) { this.name = name; } … } -
Tips & Tricks - Modelos Todos os inteiros são mapeados
para long, inclusive os Wrappers. Não é possível armazenar null para nenhum tipo diferente de RealmObject ou RealmLists. Os getters e setters são obrigatórios para todas as propriedades não anotadas com @Ignore. Getters e Setters são alterados depois pelo Realm, então qualquer implementação diferente é descartada. -
Tips & Tricks - Modelos Todos os atributos devem ser
privados. Métodos e atributos estáticos são liberados. @PrimaryKey não pode ser usada em mais de um atributo. @PrimaryKey já define implicitamente o @Index para o atributo. -
Tips & Tricks - Modelos Nome da classe deve ter
no máximo 57 caracteres. Nome de atributo deve ter no máximo 63 caracteres Datas são armazenadas com precisão de segundos, no período 13/12/1900 e 19/01/2038. Strings e byte[] devem ter no máximo 16mb. -
Transações Realm realm = Realm.getInstance(this); realm.beginTransaction(); // Insere, altera ou
remove objetos da base realm.commitTransaction(); realm.cancelTransaction(); Realm realm = Realm.getInstance(this); realm.executeTransaction((realm) -> { // Insere, altera ou remove objetos da base }); Realm realm = Realm.getInstance(this); realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { // Insere, altera ou remove objetos da base } }); Explicitamente Realm + Lambda Realm -
Tips & Tricks - Transações São obrigatórias para qualquer alteração
na base de dados. Dados só são persistidos no disco após o commit da transação. Operações de escrita no banco bloqueiam outras transações de escrita e podem demorar. ATENÇÃO: Não faça operações de escrita no banco na UI Thread. -
Tips & Tricks - Transações Divida o processo em criar
objetos e gravar no banco. Escritas no banco não bloqueiam a leitura do mesmo. Transações aninhadas (uma transação dentro de outra transação) não são suportadas e geram exceção. -
Criando objetos User user = realm.createObject(User.class); // Create a new
object user.setName("John"); user.setEmail("[email protected]"); User user = new User("John"); user.setEmail("[email protected]"); User realmUser = realm.copyToRealm(user); String json = ...; realm.createObjectFromJson(User.class, json); String json = ...; realm.createOrUpdateObjectFromJson(User.class, json); -
Tips & Tricks - Objetos Manipulação de objetos deve sempre
ocorrer dentro de uma transação. O objeto só pode ser usado na Thread em que ele foi criado. Pode-se criar um Wrapper para o objeto para poder transitá-lo entre threads e inserir métodos nele. Cuidado com restrições definidas por PrimaryKey ao inserir ou atualizar objetos. -
Consultas // Criando a consulta para pegar todos os usuários.
RealmQuery<User> query = realm.where(User.class); // Adiciona as condições query.equalTo("nome", "Joao"); query.or().equalTo("nome", "Pedro"); // Executa a consulta RealmResults<User> resultado = query.findAll(); // Fazendo tudo junto RealmResults<User> resultado = realm.where(User.class) .equalTo("nome", "Joao") .or() .equalTo("nome", "Pedro") .findAll(); -
Consultas // Agrupando Operadores Lógicos RealmResults<User> resultado = realm.where(User.class) .greaterThan(“idade”,
10) .beginGroup() .equalTo("nome", "Joao") .or() .contains("nome", “Paulo") .endGroup() .findAll(); // Encadeando consultas RealmResults<User> adolescentes = realm.where(User.class) .between(“idade”, 13, 20) .findAll(); User primeiroJoao = adolescentes.where() .equalTo("nome", "Joao") .findFirst(); -
Consultas // Funções de agregação long sum = resultado.sum("idade").longValue(); long
min = resultado.min("idade").longValue(); long max = resultado.max("idade").longValue(); double average = resultado.average("idade"); long matches = result.size(); // Ordenando o resultado RealmResults<User> result = realm.where(User.class).findAll(); result.sort("idade"); // Sort ascending result.sort(""idade", RealmResults.SORT_ORDER_DESCENDING); // Ordenando já na consulta RealmResults<User> result = realm.where(User.class).findAllSorted("idade"); -
Consultas public class User extends RealmObject { ... private RealmList<Email>
emails; ... } public class Email extends RealmObject { ... private boolean active; ... } RealmResults<Contact> contacts = realm.where(Contact.class) .equalTo("emails.active", true) .findAll(); public class User extends RealmObject { ... private RealmList<Email> emails; ... } public class Email extends RealmObject { ... private boolean active; ... } RealmResults<Contact> contacts = realm.where(Contact.class) .equalTo("emails.active", true) .equalTo("emails.active", false) .findAll(); -
Tips & Tricks - Consultas Cuidado com o nome das
propriedades na hora de filtrar para evitar erros de digitação. Só é possível ordenar utilizando os campos que estão no modelo de retorno. Não é possível fazer GROUP BY como é feito no SQL. Todas as consultas são LAZY. -
Remoção // Remover o objeto de um resultado. result.remove(0); result.removeLast();
// Remover um objeto específico. User usuario = result.get(5); usuario.removeFromRealm(); // Remover todos os objetos de um resultado. result.clear(); -
Tips & Tricks - Geral public abstract class AbstractRealmPersistenceService {
private Context context; private Realm realm; private int currentThreadId; public AbstractRealmPersistenceService(Context context) { this(context, null); } public AbstractRealmPersistenceService(Context context, Realm realm) { this.context = context; this.realm = realm; this.currentThreadId = android.os.Process.myTid(); } protected Realm getRealm() { this.reloadRealm(); return this.realm; } private void reloadRealm() { int threadId = android.os.Process.myTid(); if(this.currentThreadId != threadId || this.realm == null) { this.realm = Realm.getInstance(this.context); this.currentThreadId = threadId; } } } -
Tips & Tricks - Geral Cuidado com a transição entre
Threads, principalmente se você faz operações em Background.