【Android】Room: un reemplazo para SQLite

¿Por qué se reemplazó SQLite por Room?

¿Por qué se reemplazará SQLite?

SqliteTiene una historia de más de 20 años desde su creación en 2000. En estos más de 20 años, la Sqliteversión 1.0 original se ha actualizado a la versión 3.0 actual, sin embargo, incluso con la última versión 2.3.0 compatible con Android, Todavía está disponible en Android, pero todavía hay una serie de deficiencias, como las siguientes:

  • No hay validación en tiempo de compilación de consultas SQL sin formato.
  • Se requiere una gran cantidad de código repetitivo para convertir entre consultas SQL y objetos de datos.
  • Si bien estas API son potentes, son de nivel bastante bajo y su uso requiere mucho tiempo y esfuerzo.

En respuesta a Sqliteuna serie de problemas, el objetivo de realm(aplicable a ios, Android), ObjectBox(cross-end, afirmando ser el más rápido) greenDaoy otras bases de datos locales es reemplazar SQLite, e incluso más tarde, incluso el funcionario lanzó una nueva base de datos. - — ¿ RoomSe va a eliminar esto por completo Sqlite?

La respuesta es No. Las bases de datos anteriores greenDAO están siendoRoom modificadas y optimizadas. Es un producto desarrollado por el equipo de desarrollo de. Recomendan la base de datos a todos en la página de inicio de Github, pero ha actualizado durante más de un año. Quizás, el pico de Sí ha pasado y es difícil mantenerse en pie. la parte superior nuevamente, por lo que poco a poco están comenzando a usarlo, perdiendo la esperanza en el futuro (suposición personal).SqliteObjectBoxgreenDAO greenDAOObjectBoxgreenDAOgreenDao

Entonces, ¿por qué SQLitese reemplaza Roomen lugar de greenDao? Personalmente, creo que esto se debe enteramente al "anuncio oficial" oficial. En la página de introducción y la guía de uso que se encuentran en el sitio web oficial de desarrolladores de Android SQLite, encontrará palabras como esta:

Recomendamos encarecidamente utilizar la biblioteca Room Persistence como capa de abstracción para acceder a la información en las bases de datos SQLite de su aplicación
.

Insertar descripción de la imagen aquí
Las razones para rendirnos SQLitey persuadirnos para que lo usemos Roomson SQLitelas desventajas y Roomlas ventajas.

Roomventaja:

  • Ruta de migración de base de datos simplificada.
  • Validación en tiempo de compilación de consultas SQL.
  • Los comentarios convenientes minimizan la duplicación y el código repetitivo propenso a errores.

Sala Integrada

La habitación contiene tres componentes principales, a saber:

  • Base de datos: una clase de base de datos que contiene una base de datos y sirve como punto de acceso principal para la conexión subyacente a los datos persistentes de una aplicación.
  • Entidad: representa la entidad de datos de la tabla en la base de datos de la aplicación.
  • Dao: objeto de acceso a datos que proporciona métodos que su aplicación puede utilizar para consultar, actualizar, insertar y eliminar datos en la base de datos.

Importar dependencias

implementation("androidx.room:room-runtime:2.4.2")
annotationProcessor("androidx.room:room-compiler:2.4.2")

// 使用 Kotlin 注释处理工具 (kapt)
kapt("androidx.room:room-compiler:2.4.2")

Nota: El complemento Kotlin admite procesadores de anotaciones como Dagger o DBFlow. Para que funcionen con las clases de Kotlin, kaptes necesario aplicar complementos kotlin-kapt.

apply plugin: 'kotlin-kapt'

Haga clic para ver las dependencias de la última versión.

Hay tres pasos para usar Room, a saber, base de datos, entidad y Dao. Los datos solo se pueden escribir, modificar y realizar otras operaciones después de que se completa cada creación.

Entidad (entidad de datos)

En Room, puedes definir entidades para representar los objetos que deseas almacenar. Cada entidad corresponde a una tabla en la base de datos Room asociada, y cada instancia de una entidad representa una fila de datos en la tabla correspondiente.

La versión Kotlin de Entity está escrita de manera diferente a la versión Java de Entity. La forma normal de escribir la versión Java de Entity es crear una nueva clase de entidad e implementar los métodos get y set de las variables. La versión Kotlin de Entity usa palabras clave En Kotlin, se data classutiliza la clase marcada data class. Es una clase de datos, que anulará automáticamente KotlinAnydeequals(other: Any?)los . Para obtener información más detallada, vaya a → Clase de datos de Kotlin (Datos).hashCode()toString()

La clase de datos declarada data classcomo Room debe declararse mediante @Entityanotaciones. De forma predeterminada, Room utilizará el nombre de la clase como nombre de la tabla de la base de datos. Si no desea que el nombre de la clase sea el mismo que el nombre de la tabla de la base de datos, puede @Entityestablecer tableNameparámetros en la anotación, como: @Entity(tableName = "自定义的数据库表名"), agregue parámetros Después de eso, el nombre de la tabla de la base de datos generada por esta clase ya no será el nombre de la clase.

@Entity
data class Classes(
    @PrimaryKey val classesId: String,
    @ColumnInfo val classesName: String
)

Otras notas

Anotación Describir
@Clave primaria Se utiliza para identificar de forma única cada fila en la tabla de base de datos correspondiente.
@ColumnaInfo Definir los nombres de las columnas de la tabla de datos.
@Ignorar No agregue campos a la tabla de datos
@NonNull El valor de retorno de un campo o método no puede ser nulo

@EntityPara un uso detallado, consulte: Uso de entidades de habitación para definir datos

Dao (objeto de acceso a datos)

Dao: proporciona métodos utilizados por el resto de la aplicación para interactuar con los datos de la tabla de datos.

Dao es una clase de interfaz. No es necesario escribir un cuerpo de método. En su lugar, se pueden usar anotaciones directamente. La adición, eliminación, modificación y consulta corresponden a las siguientes cuatro anotaciones:

Anotación Describir
@Insertar aumentar
@Borrar borrar
@Actualizar cambiar
@Consulta controlar

Las anotaciones se utilizan de la siguiente manera:

@Dao
interface ClassesDao {
    
    
    /**
     * 增加多个班级
     */
    @Insert
    fun addMultipleClasses(vararg classes: Classes)
	/**
     * 删除某条数据
     */
    @Delete
    fun deleteClasses(classes: Classes)
    /**
     * 修改某条数据
     */
    @Update
    fun updateClasses(classes: Classes)
    /**
     * 查询classes表的数据
     */
    @Query("select * from classes")
    fun getAllClasses() : List<Classes>
}

En Room, la consulta con valor se representa con dos puntos. El siguiente código indica que el nombre de clase a buscar es igual al valor pasado al llamar a la interfaz.

@Query("select * from classes where className = :classesName")
fun getAllClasses(classesName: String) : List<Classes>

Para conocer el uso detallado de Dao, consulte: Uso de Room DAO para acceder a datos

Base de datos

Se han definido Entidad y Dao. El último paso es crear una clase de base de datos para guardar los datos. La clase creada debe cumplir las tres condiciones de la base de datos:

  • La clase debe ser RoomDatabaseuna clase abstracta que extienda la clase.
  • Para cada clase Dao asociada con una base de datos, la clase de base de datos debe definir un método abstracto que toma cero parámetros y devuelve una instancia de la clase Dao.
  • La clase debe tener una anotación @Databaseque contenga entitiesuna matriz que enumere todas las entidades de datos asociadas con la base de datos (incluida la versión de la base de datos).
@Database(entities = [Classes::class/*数据库包含的实体*/], version = 1, exportSchema = false)
abstract class SchoolDatabase : RoomDatabase() {
    
    
    /**
     * 调用该方法获取Dao,来调用Classes表的接口方法
     */
    abstract fun classDao(): ClassesDao
}

usar

Room.databaseBuilder(applicationContext, SchoolDatabase::class.java, "数据库名称")
     .build()
     .classDao()
     .addClasses(classes)

Efecto

Insertar descripción de la imagen aquí

migración de datos

¿Por qué es necesario migrar la base de datos?

Puede encontrar un problema de este tipo durante el desarrollo de una base de datos local: después de modificar los campos de la base de datos, se producirá un bloqueo al reiniciar.

Algunos estudiantes que encuentran este problema pueden usar palabras clave como esta para buscar: soluciones para fallas en la modificación de campos de bases de datos. Los resultados de la búsqueda le indicarán que desinstale la aplicación y la reinstale, y el problema se resolverá. Sin embargo, este método aparentemente correcto es en realidad fatal.

La base de datos local se modifica, empaqueta y publica una vez. Si el usuario utiliza la base de datos local después de actualizar la aplicación, Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.se informará un error de excepción.

Insertar descripción de la imagen aquí
Si la interfaz de una aplicación no se carga en 8 segundos, se perderá el 70% de los usuarios. Esta es la regla de los 8 segundos. Entonces, ¿cuántos usuarios se perderán si falla una vez? Para resolver los problemas anteriores, solo se puede migrar la base de datos y la migración de datos se divide en migración automática y migración manual.

Migración automática

La migración automática proporciona cuatro anotaciones para la migración automática, que son:

Cómo usarlo:

// 版本更新前的数据库类.
@Database(
  version = 1,
  entities = [User::class]
)
abstract class AppDatabase : RoomDatabase() {
    
    
  ...
}

// 版本更新后的数据库类.
@Database(
  version = 2,
  entities = [User::class],
  exportSchema = true,
  autoMigrations = [
    AutoMigration (from = 1, to = 2)
  ]
)
abstract class AppDatabase : RoomDatabase() {
    
    
  ...
}

Dado que actualmente el funcionario solo proporciona las cuatro anotaciones anteriores para la migración automática, cómo agregar campos se ha convertido en un misterio. Si conoció los nuevos campos de la tabla de datos para la migración automática mientras miraba este artículo, espero que pueda unirse a nosotros en el área de comentarios. .compartir.

Nota: 1. Se debe configurar
la migración automática para evitar errores en la migración. 2. La migración automática solo es aplicable a 2.4.0-alpha01 y versiones superiores. Para versiones inferiores y situaciones que involucran cambios de arquitectura complejos, se debe utilizar la migración manual.exportSchematrue

Artículo de referencia: Migración de la base de datos de la sala

Migración manual

El primer paso en la migración manual de una base de datos es modificar la estructura de la tabla de datos.

@Entity
data class Classes(
    @PrimaryKey(autoGenerate = true) val classesId: Int = 0,
    @ColumnInfo(name = "className") var classesName: String,
    // 新增的列
    @ColumnInfo(name = "classesNum") var classesNum: String
)

El método utilizado para la migración manual RoomDatabase.Builderes addMigrations(@NonNull Migration... migrations)colocar la nueva Migrationclase para completar la migración.

La capa inferior de Room usa SQLite. La migración de datos usa el execSQL(String sql)método SQLite para ejecutar declaraciones SQL para modificar la base de datos y completar la migración. El código es el siguiente:

var db: SchoolDatabase ?= null
// 单例模式的双重检查锁
fun getDataBase(context: Context) : SchoolDatabase{
    
    
    if (db == null){
    
    
        synchronized(SchoolDatabase::class.java){
    
    
            if (db == null){
    
    
                db = Room.databaseBuilder(context.applicationContext, SchoolDatabase::class.java, "school")
                    // .fallbackToDestructiveMigration()
                    // 添加数据迁移
                    .addMigrations(MIGRATION_1_TO_2)
                    .build()
            }
        }
    }
    return db as SchoolDatabase;
}

// Migration实例的两个参数指的是当前版本升级到什么版本
val MIGRATION_1_TO_2 : Migration = object : Migration(1, 2) {
    
    
    override fun migrate(database: SupportSQLiteDatabase) {
    
    
        //  添加新的列使用 底层SQLite + sql 语法,其它增删改查亦是如此
        database.execSQL("alter table classesNum add column 新增的列名 列名的数据类型 default 'null'")
    }
}

Finalmente, no olvide cambiar los parámetros @Databasede anotación en el nombre de la clase de la base de datos a la última versión y ejecutar nuevamente para completar la migración.version

Referencia: tutorial básico de desarrollo de Android

Usado con RxJava

Cuando Room realiza operaciones de base de datos, utiliza un subproceso de forma predeterminada. Si es necesario ejecutarlo en el hilo principal, se puede llamar para Room.databaseBuilderdeshabilitar allowMainThreadQueries()la verificación de consulta del hilo principal de Room. Sin embargo, esta operación no se recomienda, ya que aumentará la probabilidad de desencadenar ANR.

ThreadSi crea uno nuevo e implementa la interfaz cada vez que realiza una operación de Sala Runnable, ¿no sería más fácil activar ANR?

Con este fin, el funcionario ha lanzado una biblioteca que se utiliza junto con Rxjava para facilitar el cambio entre subprocesos.

// optional - RxJava3 support for Room
implementation("androidx.room:room-rxjava3:2.4.2")
// RxJava3
implementation ("io.reactivex.rxjava3:rxjava:3.1.3")
implementation ("io.reactivex.rxjava3:rxandroid:3.0.0")

Para operaciones específicas combinadas con RxJava, consulte los artículos:
1. Práctica de la base de datos de Room: uso y encapsulación con RxJava
2. Room con RxJava2, métodos de uso, experiencia y precauciones


Código para este artículo: Sala [Android] - Demostración de reemplazo de SQLite

Documento de referencia
1. Ejemplo de código de Android Room
2. Desarrolladores de Android —— Room
3. Desarrolladores de Android —— Guía de uso de Room
4. Desarrolladores de Android —— Definición de datos mediante entidades de Room

Supongo que te gusta

Origin blog.csdn.net/baidu_41616022/article/details/125424197
Recomendado
Clasificación