¿Por qué se reemplazó SQLite por Room?
Tabla de contenido
¿Por qué se reemplazará SQLite?
Sqlite
Tiene una historia de más de 20 años desde su creación en 2000. En estos más de 20 años, la Sqlite
versió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 Sqlite
una serie de problemas, el objetivo de realm
(aplicable a ios, Android), ObjectBox
(cross-end, afirmando ser el más rápido) greenDao
y otras bases de datos locales es reemplazar SQLite
, e incluso más tarde, incluso el funcionario lanzó una nueva base de datos. - — ¿ Room
Se 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).Sqlite
ObjectBox
greenDAO
greenDAO
ObjectBox
greenDAO
greenDao
Entonces, ¿por qué SQLite
se reemplaza Room
en 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
.
Las razones para rendirnos SQLite
y persuadirnos para que lo usemos Room
son SQLite
las desventajas y Room
las ventajas.
Room
ventaja:
- 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,
kapt
es necesario aplicar complementoskotlin-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 class
utiliza la clase marcada data class
. Es una clase de datos, que anulará automáticamente KotlinAny
deequals(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 class
como Room debe declararse mediante @Entity
anotaciones. 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 @Entity
establecer tableName
pará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 |
@Entity
Para 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
RoomDatabase
una 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
@Database
que contengaentities
una 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
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.
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:
- @DeleteTable (anotación repetible utilizada para declarar una tabla eliminada)
- @RenameTable (anotación repetible utilizada para declarar una tabla renombrada)
- @DeleteColumn (anotación repetible utilizada para declarar columnas eliminadas)
- @RenameColumn (anotación repetible utilizada para declarar columnas renombradas)
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.exportSchema
true
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.Builder
es addMigrations(@NonNull Migration... migrations)
colocar la nueva Migration
clase 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 @Database
de 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.databaseBuilder
deshabilitar 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.
Thread
Si 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