Slide 1

Slide 1 text

Persistência com Realm.io Pedro Salomão @ppgsalomao ppgsalomao@gmail.com / pedro@onyo.com

Slide 2

Slide 2 text

#whoami

Slide 3

Slide 3 text

Persistência O que é persistência? Quando devemos buscar uma biblioteca? Realm resolve todos os problemas de persistência? Existe bala de prata?

Slide 4

Slide 4 text

O que precisamos saber para usar o Realm?

Slide 5

Slide 5 text

Must know Android Threads ProGuard

Slide 6

Slide 6 text

Realm.io

Slide 7

Slide 7 text

Documentação https://realm.io/

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Modelos

Slide 10

Slide 10 text

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; } … }

Slide 11

Slide 11 text

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.

Slide 12

Slide 12 text

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.

Slide 13

Slide 13 text

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.

Slide 14

Slide 14 text

Transações

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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.

Slide 17

Slide 17 text

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.

Slide 18

Slide 18 text

Gravando no Banco

Slide 19

Slide 19 text

Criando objetos User user = realm.createObject(User.class); // Create a new object user.setName("John"); user.setEmail("john@corporation.com"); User user = new User("John"); user.setEmail("john@corporation.com"); User realmUser = realm.copyToRealm(user); String json = ...; realm.createObjectFromJson(User.class, json); String json = ...; realm.createOrUpdateObjectFromJson(User.class, json);

Slide 20

Slide 20 text

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.

Slide 21

Slide 21 text

Fazendo consultas

Slide 22

Slide 22 text

Consultas // Criando a consulta para pegar todos os usuários. RealmQuery query = realm.where(User.class); // Adiciona as condições query.equalTo("nome", "Joao"); query.or().equalTo("nome", "Pedro"); // Executa a consulta RealmResults resultado = query.findAll(); // Fazendo tudo junto RealmResults resultado = realm.where(User.class) .equalTo("nome", "Joao") .or() .equalTo("nome", "Pedro") .findAll();

Slide 23

Slide 23 text

Consultas // Agrupando Operadores Lógicos RealmResults resultado = realm.where(User.class) .greaterThan(“idade”, 10) .beginGroup() .equalTo("nome", "Joao") .or() .contains("nome", “Paulo") .endGroup() .findAll(); // Encadeando consultas RealmResults adolescentes = realm.where(User.class) .between(“idade”, 13, 20) .findAll(); User primeiroJoao = adolescentes.where() .equalTo("nome", "Joao") .findFirst();

Slide 24

Slide 24 text

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 result = realm.where(User.class).findAll(); result.sort("idade"); // Sort ascending result.sort(""idade", RealmResults.SORT_ORDER_DESCENDING); // Ordenando já na consulta RealmResults result = realm.where(User.class).findAllSorted("idade");

Slide 25

Slide 25 text

Consultas public class User extends RealmObject { ... private RealmList emails; ... } public class Email extends RealmObject { ... private boolean active; ... } RealmResults contacts = realm.where(Contact.class) .equalTo("emails.active", true) .findAll(); public class User extends RealmObject { ... private RealmList emails; ... } public class Email extends RealmObject { ... private boolean active; ... } RealmResults contacts = realm.where(Contact.class) .equalTo("emails.active", true) .equalTo("emails.active", false) .findAll();

Slide 26

Slide 26 text

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.

Slide 27

Slide 27 text

Removendo da Base

Slide 28

Slide 28 text

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();

Slide 29

Slide 29 text

Utilitários Integrando com a Aplicação

Slide 30

Slide 30 text

Utilitários Notificações Migrações Criptografia RealmBaseAdapter

Slide 31

Slide 31 text

Integração com outras bibliotecas Parceler Robolectric

Slide 32

Slide 32 text

Geral

Slide 33

Slide 33 text

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; } } }

Slide 34

Slide 34 text

Tips & Tricks - Geral Cuidado com a transição entre Threads, principalmente se você faz operações em Background.

Slide 35

Slide 35 text

Dúvidas? Pedro Salomão @ppgsalomao

Slide 36

Slide 36 text

Obrigado! Estamos contratando! Pedro Salomão @ppgsalomao ppgsalomao@gmail.com / pedro@onyo.com