Android Room使用

2019-05-06  本文已影响0人  fomin

简介

Room库在SQLite上提供了一个抽象层,允许在充分利用SQLite的功能的同时进行更健壮的数据库访问。可以在运行的app设备上创建一个应用数据缓存,这个缓存作为app的唯一数据来源,不管用户是否有连接网络,都允许用户在app中查看相关信息。
Room有三个主要的组成部分:Database,Entity,DAO。

在运行时,您可以通过调用Room.databaseBuilder()或Room.inMemoryDatabaseBuilder()来获取数据库实例。

Room不同组成的相关关系图

引用

在project的build.gradle添加google的maven仓库

allprojects {
    repositories {
        google()
        jcenter()
    }
}

在module的build.gradle添加Room的引用,Room还提供了Rxjava2和Guava的数据处理

dependencies {
    def room_version = "2.1.0-alpha07"

    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation "androidx.room:room-ktx:$room_version"

    // optional - RxJava support for Room
    implementation "androidx.room:room-rxjava2:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "androidx.room:room-guava:$room_version"

    // Test helpers
    testImplementation "androidx.room:room-testing:$room_version"
}

Enity

下面定义一个User的实体

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "second_name") val secondName: String?,
    @Ignore val desc: String?
)
@Entity(indices = [Index("name"), Index(value = ["first_name", "second_name"])])
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "second_name") val secondName: String?,
    @Ignore val desc: String?
)
@Entity(foreignKeys = [ForeignKey(entity = User::class, parentColumns = ["uid"], childColumns = ["user_id"])])
data class Order(
    @PrimaryKey val orderNo: String,
    @ColumnInfo val address: String,
    @ColumnInfo(name = "user_id") val userId: Int
)
@Embedded(prefix = "order") val order: Order?

DAO

定义一个User的数据访问类

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM user where first_name LIKE :first AND second_name LIKE :last LIMIT 1 ")
    fun findByName(first: String, last: String): User

    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)
    
    @Update
    fun updateUsers(vararg users: User)
}

在执行查询时,想让UI在数据更改时自动更新。可以在查询方法使用 LiveData 类行的返回值。当数据更新时 Room 会自动生成所需的代码已更新LiveData。

@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun getList(userIds: IntArray): LiveData<List<User>>

可以从定义的查询中返回 RxJava2 的 Publisher 和 Flowable 对象

@Query("SELECT * FROM user where first_name LIKE :first AND second_name LIKE :last LIMIT 1 ")
fun getByName(first: String, last: String): Flowable<User>

Database

@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

创建完完成后使用以下代码获取数据库实例,并且使用单例来访问

var db = Room.databaseBuilder(
    getApplicationContext(),
    AppDatabase::class.java, "database-name"
).build()

迁移数据库

在APP升级时可能需要更改数据库来策应新的功能。如果不希望数据库中的数据丢失,
Room 允许我们编写 Migration ,以此来迁移数据;如果使用fallbackToDestructiveMigration(),数据库的内容都被清空。
每个迁移类制定一个开始版本和结束版本。在运行时,Room会运行每个Migration类的migrate()方法,并使用正确的顺序将数据库迁移到更高版本。
首先,需要更新Database的版本号

@Database(entities = arrayOf(User::class), version = 2)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

其次添加一个version:1->2的migration

val MIGRATION_1_2: Migration = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE User " + " ADD COLUMN mobile TEXT")
    }
}

最后把migration 添加到 databaseBuilder,addMigrations提供可选参数,支持多版本迁移,传入多个migration。

var db = Room.databaseBuilder(
    getApplicationContext(),
    AppDatabase::class.java, "database-name"
).allowMainThreadQueries()
    .addMigrations(MIGRATION_1_2).build()

Room的基本用法介绍已经END。

上一篇 下一篇

猜你喜欢

热点阅读