Android采用sqlite作为数据库存储,Room就是Google推出的自己的ORM(Object Relational Mapping)。

Room的架构图:

room文件BIOS room文件是什么_数据库

  • Entity:一个Entity对应于数据库中的一张表。Entity类是Sqlite表结构对Java类的映射,在Java中可以被看作一个Model类。
  • Dao:即Data Access Objects,数据访问对象,可以通过它来访问数据。
    一个Entity代表一张表,而每张表都需要一个Dao对象,用于对表进行增/删/改/查。Room数据库在被实例化之后,可以通过数据实例得到Dao对象(Get Dao),进而通过Dao对象对表中的数据进行操作。
使用Room
  1. 在app的build.gradle中添加Room的相关依赖
implementation 'androidx.room:room-runtime:2.2.5'
    kapt "androidx.room:room-compiler:2.2.5"
  1. 创建一个Entity,即一张表。新建一个类文件,并在类文件的上方添加@Entity标签。
@Entity(tableName = "student")
data class Student(

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
    var id: Int?,

    @ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
    var name: String?,

    @ColumnInfo(name = "age", typeAffinity = ColumnInfo.TEXT)
    var age: String?
)
  • @Entity标签用于将Student类与Room中的数据表对应起来。tableName属性可以位数据表设置表名,若不设置,则表名与类名相同。
  • @PrimaryKey标签用于指定该字段作为表的主键
  • @ColumnInfo标签可用于设置该字段存储在数据库表中的名字,并指定字段类型。
  • @Ignore标签用来告诉Room忽略该字段或方法。
  1. 针对上面的Entity,需要定义一个Dao接口文件,以便于对Entity进行访问。需要在文件上方添加@Dao标签。
@Dao
interface StudentDao {
    @Insert
    fun insertStudent(student: Student)

    @Delete
    fun deleteStudent(student: Student)

    @Update
    fun updateStudent(student: Student)

    @Query("SELECT * FROM student")
    fun getStudentList(): LiveData<List<Student>>

    @Query("SELECT * FROM student WHERE id = :id")
    fun getStudentById(id: Int)
}
  1. 定义好Entity和Dao后,接下来创建数据库。
const val MY_DATABASE_NAME = "my_db"

@Database(entities = [Student::class], version = 1)
abstract class MyDatabase : RoomDatabase() {

    companion object {
        val instance = Single.sin
    }

    private object Single {
        val sin: MyDatabase =
            Room.databaseBuilder(MyApplication.instance(), MyDatabase::class.java, MY_DATABASE_NAME)
                .build()

    }

    abstract fun studentDao(): StudentDao
}
@Database标签用于告诉系统这是Room数据库对象。entities属性用于指定该数据库有哪些表,若需要建立多张表,则表名以逗号相隔开;version属性用于指定数据库版本号,数据库升级依据版本号进行判断。
数据库类需要继承自RoomDatabase,并通过Room.databaseBuilder()结合单例设计模式完成创建。
  1. 数据库和表创建完成后,就可以通过单例模式调用数据库进行增/删/改/查,接口调用时需要注意线程切换。
与LiveData、ViewModel结合使用

room文件BIOS room文件是什么_android_02


当Room数据库中的数据发生变化时,通过LiveData组件通知View层,实现数据的自动更新。

class StudentViewModel(application: MyApplication): AndroidViewModel(application) {
    private val myDatabase = MyDatabase.instance

    val liveDataStudent = myDatabase.studentDao().getStudentList()

}
private val studentViewModel: StudentViewModel by viewModels()
studentViewModel.liveDataStudent.observe(viewLifecycleOwner, {
    students -> { TODO("显示students列表")}
})
数据库升级

Android提供了一个名为Migration的类来对Room进行升级。

public Migration(int startVersion, int endVersion) {
        this.startVersion = startVersion;
        this.endVersion = endVersion;
    }

Migration有两个参数,startVersion和endVersion,startVersion表示当前数据库版本,endVersion表示将要升级到的版本。

val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                TODO("执行升级相关操作")
            }
        }

在Migration中编写完升级方案后,需要通过addMigrations()方法,将升级方案添加到Room。

Room.databaseBuilder(MyApplication.instance(), MyDatabase::class.java, MY_DATABASE_NAME)
                .addMigrations(MIGRATION_1_2)
                .build()
异常处理

Room在升级过程中没有匹配到相应的Migration,会导致应用程序崩溃,可以在创建数据库时加入fallbackToDestructiveMigration()方法,此方法能在升级异常时,重新创建数据表。但需要注意,虽然应用程序不会崩溃,但所有数据会丢失。

Room.databaseBuilder(MyApplication.instance(), MyDatabase::class.java, MY_DATABASE_NAME)
    .addMigrations(MIGRATION_1_2)
    .fallbackToDestructiveMigration()
    .build()
Schema文件

Room提供了一项功能,在每次数据库升级的过程中,会导出一个Schema文件,这是一个json格式的文件,其中包含了数据库的所有基本信息。
可以在app的build.gradle文件中指定schema文件的导出位置。

javaCompileOptions {
        annotationProcessorOptions {
            arguments = ["room.schemaLocation":"$projectDir/ schemas".toString()]
        }
    }

Room默认导出Schema文件,如果不想导出,可以在数据库标签@Database中指定exportSchema=false

销毁与重建策略
  1. 创建一张符合表结构要求的临时表temp
  2. 将数据从旧表复制到临时表temp
  3. 删除旧表
  4. 将临时表temp重命名为原表名
预填充数据

如果已有数据库文件.db,可以放到assets目录下,然后使用createFromAsset()方法创建Room数据库;或者将.db文件放到SD卡下,使用createFromFile()方法来创建Room数据库。

Room.databaseBuilder(MyApplication.instance(), MyDatabase::class.java, MY_DATABASE_NAME)
    .addMigrations(MIGRATION_1_2)
    .fallbackToDestructiveMigration()
    .createFromAsset("database/students.db")
    .build()