Migrar de SQLite para Room

A biblioteca de persistência do Room oferece vários benefícios em comparação a usar as APIs SQLite diretamente.

  • Verificação de consultas SQL durante a compilação
  • Anotações de conveniência que minimizam o código boilerplate repetitivo e propenso a erros
  • Caminhos de migração de banco de dados simplificados

Se o app usa uma implementação do SQLite que não seja o Room, leia esta página e veja como migrar o app para usar o Room. Se o Room for a primeira implementação do SQLite que você está usando no app, consulte Salvar dados em um banco de dados local usando o Room para ver informações básicas de uso.

Etapas da migração

Siga as etapas abaixo para migrar a implementação do SQLite para Room. Caso a implementação do SQLite use um banco de dados grande ou consultas complexas, é possível migrar gradualmente para o Room. Consulte como usar uma estratégia de Migração incremental.

Atualizar dependências

Para usar o Room no app, é necessário incluir as dependências adequadas no arquivo build.gradle do app. Consulte Configuração para ver as dependências mais atualizadas do Room.

Atualizar classes de modelo para entidades de dados

O Room usa entidades de dados para representar as tabelas no banco de dados. Cada classe representa uma tabela e tem campos que representam as colunas da tabela. Siga estas etapas de atualização das classes de modelo existentes para que elas passem a ser entidades do Room:

  1. Adicione a anotação @Entity à declaração de classe para indicar que essa é uma entidade do Room. Você também pode usar a propriedade tableName para indicar que a tabela resultante precisa ter um nome diferente do nome da classe.
  2. Inclua a anotação @PrimaryKey no campo da chave primária.
  3. Caso qualquer uma das colunas na tabela resultante tenha um nome diferente do nome do campo correspondente, inclua a anotação @ColumnInfo no campo e defina o nome de coluna correto na propriedade name.
  4. Caso a classe tenha campos que você não quer manter no banco de dados, insira a anotação @Ignore para indicar que o Room não precisa criar colunas para esses campos na tabela correspondente.
  5. Se a classe tiver mais de um método de construtor, indique qual construtor o Room vai usar. Para isso, adicione a anotação @Ignore a todos os outros construtores.

Kotlin

@Entity(tableName = "users")
data class User(
  @PrimaryKey
  @ColumnInfo(name = "userid") val mId: String,
  @ColumnInfo(name = "username") val mUserName: String?,
  @ColumnInfo(name = "last_update") val mDate: Date?,
)

Java

@Entity(tableName = "users")
public class User {

  @PrimaryKey
  @ColumnInfo(name = "userid")
  private String mId;

  @ColumnInfo(name = "username")
  private String mUserName;

  @ColumnInfo(name = "last_update")
  private Date mDate;

  @Ignore
  public User(String userName) {
    mId = UUID.randomUUID().toString();
    mUserName = userName;
    mDate = new Date(System.currentTimeMillis());
  }

  public User(String id, String userName, Date date) {
    this.mId = id;
    this.mUserName = userName;
    this.mDate = date;
  }

}

Criar DAOs

O Room usa objetos de acesso a dados (DAOs, na sigla em inglês) para definir métodos que acessam o banco de dados. Siga as orientações em Como acessar dados usando DAOs do Room para substituir os métodos de consulta existentes por DAOs.

Criar uma classe de banco de dados

As implementações do Room usam uma classe de banco de dados para gerenciar uma instância do banco de dados. A classe do banco de dados precisa estender RoomDatabase e referenciar todas as entidades e os DAOs definidos.

Kotlin

@Database(entities = [User::class], version = 2)
@TypeConverters(DateConverter::class)
abstract class UsersDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Java

@Database(entities = {User.class}, version = 2)
@TypeConverters(DateConverter.class)
public abstract class UsersDatabase extends RoomDatabase {
  public abstract UserDao userDao();
}

Definir um caminho de migração

Como o número da versão do banco de dados está mudando, é necessário definir um objeto Migration a fim de indicar um caminho de migração para que o Room mantenha os dados atuais no banco de dados. Desde que o esquema do banco de dados não mude, essa implementação pode ficar vazia.

Kotlin

val MIGRATION_1_2 = object : Migration(1, 2) {
  override fun migrate(database: SupportSQLiteDatabase) {
    // Empty implementation, because the schema isn't changing.
  }
}

Java

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
  @Override
  public void migrate(SupportSQLiteDatabase database) {
    // Empty implementation, because the schema isn't changing.
  }
};

Para saber mais sobre os caminhos de migração de banco de dados no Room, consulte Migrar seu banco de dados.

Atualizar a instanciação do banco de dados

Depois de definir uma classe de banco de dados e um caminho de migração, use Room.databaseBuilder para criar uma instância do banco de dados com o caminho de migração aplicado:

Kotlin

val db = Room.databaseBuilder(
          applicationContext,
          AppDatabase::class.java, "database-name"
        )
          .addMigrations(MIGRATION_1_2).build()

Java

db = Room.databaseBuilder(
          context.getApplicationContext(),
          UsersDatabase.class, "database-name"
        )
          .addMigrations(MIGRATION_1_2).build();

Testar a implementação

Teste sua nova implementação do Room:

Migração incremental

Se o app usar um banco de dados grande e complexo, talvez não seja possível migrar para o Room de uma só vez. Como alternativa, é possível começar implementando as entidades de dados e o banco de dados do Room e, mais tarde, migrar os métodos de consulta para os DAOs. Substitua a classe auxiliar de banco de dados personalizada pelo objeto SupportSQLiteOpenHelper recebido de RoomDatabase.getOpenHelper():

Outros recursos

Para saber mais sobre como migrar do SQLite para o Room, consulte os recursos abaixo:

Blogs