Kotlin教程

Android Room数据库(kotlin版)

本文主要是介绍Android Room数据库(kotlin版),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Room数据库集成

Room 持久性库在 SQLite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制。

依赖

def room_version = “2.2.5”

  implementation "androidx.room:room-runtime:$room_version"
  annotationProcessor "androidx.room:room-compiler:$room_version"

我使用的是kotlin开发,注意:对于基于 Kotlin 的应用,请确保使用 kapt,而不是 annotationProcessor。您还应添加 kotlin-kapt 插件。

可以配置编译选项

Room 具有以下注释处理器选项:

  1. room.schemaLocation:配置并启用将数据库架构导出到给定目录中的 JSON 文件的功能。
  2. room.incremental:启用 Gradle 增量注释处理器。 3.room.expandProjection:配置 Room 以重写查询,使其顶部星形投影在展开后仅包含 DAO 方法返回类型中定义的列。

代码段举例:

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                    "room.schemaLocation":"$projectDir/schemas".toString(),
                    "room.incremental":"true",
                    "room.expandProjection":"true"]
            }
        }
    }
}
Room三个主要组件

应用使用 Room 数据库来获取与该数据库关联的数据访问对象 (DAO)。然后,应用使用每个 DAO 从数据库中获取实体,然后再将对这些实体的所有更改保存回数据库中。最后,应用使用实体来获取和设置与数据库中的表列相对应的值。 room架构图

数据库

包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。 使用 @Database 注释的类应满足以下条件:

是扩展 RoomDatabase 的抽象类。 在注释中添加与数据库关联的实体列表。 包含具有 0 个参数且返回使用 @Dao 注释的类的抽象方法。

在运行时,您可以通过调用 Room.databaseBuilder() 或 Room.inMemoryDatabaseBuilder() 获取 Database 的实例。 databaseBuilder( ) 创建一个持久的数据库,保存在用户本地 inMemoryDatabaseBuilder() 在内存中创建一个数据库,这个数据库会随着进程的杀死而消失

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

在application初始化

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

表示数据库中的表,使用@Entry注解标注 , @Entity 注释的 tableName 属性可以自定义表名,SQLite 中的表名称不区分大小写。

@Entity (tableName = "users")
data class User(
    @PrimaryKey var id: Int,
    var firstName: String?,
    var lastName: String?
)

使用主键 : 一个Entry中至少需要一个主键,我们使用**@PrimaryKey** 来注释. 自增类型的主键,则可以设置 @PrimaryKey 的 autoGenerate 属性。 复合主键,使用 @Entity 注释的 primaryKeys 属性

   @Entity(primaryKeys = arrayOf("firstName", "lastName"))
     data class User(
        val firstName: String?,
        val lastName: String?
    )

同时可以自定义属性字段名 ,使用@ColumnInfo注释

@Entity(tableName = "users")
data class User (
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

忽略字段 @Ignore ,Room数据库在创建的时候会为每一个字段对应在数据库创建一列,如果不想entry中的某一个字段保留在数据表中,可以忽略

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val lastName: String?,
    @Ignore val picture: Bitmap?
)

如果涉及到entry继承,我们想要忽略父类中的字段 ,需要使用 @Entity 属性的 ignoredColumns 属性,这样会更加简洁

open class User {
    var picture: Bitmap? = null
}

@Entity(ignoredColumns = arrayOf("picture"))
data class RemoteUser(
    @PrimaryKey val id: Int,
    val hasVpn: Boolean
) : User()
DAO

包含用于访问数据库的方法。

@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 " +
           "last_name LIKE :last LIMIT 1")
    fun findByName(first: String, last: String): User

    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)
}

在DAO中定义方法方便使用

insert : 当您创建 DAO 方法并使用 @Insert 对其进行注释时,Room 会生成一个实现,该实现在单个事务中将所有参数插入到数据库中。 方法的返回值是当前entry主键id,可以单个插入返回一个id,也可以批量插入,返回一个List集合Id

@Dao
interface MyDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUsers(vararg users: User)

    @Insert
    fun insertBothUsers(user1: User, user2: User)

    @Insert
    fun insertUsersAndFriends(user: User, friends: List<User>)
}

update ,方法的返回值是表中更新的行数

@Dao
interface MyDao {
    @Update
    fun updateUsers(vararg users: User)
}

Delete 会从数据库中删除一组以参数形式给出的实体。这个是根据主键来查找删除的 ,方法的返回值是int,表示删除的行数

@Dao
interface MyDao {
    @Delete
    fun deleteUsers(vararg users: User)
}

Query 是最常用的,

@Dao
interface MyDao {
    @Query("SELECT * FROM user")
    fun loadAllUsers(): Array<User>
}

//条件查询 将参数传递到sql中, 使用 : 将参数绑定到sql中

@Dao
interface MyDao {
//条件查询 将参数传递到sql中, 使用 :
    @Query("SELECT * FROM user WHERE age > :minAge")
    fun loadAllUsersOlderThan(minAge: Int): Array<User>
}


@Dao
interface MyDao {
    @Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge")
    fun loadAllUsersBetweenAges(minAge: Int, maxAge: Int): Array<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :search " +
           "OR last_name LIKE :search")
    fun findUserWithName(search: String): List<User>
}

返回列的子集 大多数情况下,您只需获取实体的几个字段。例如,您的界面可能仅显示用户的名字和姓氏,而不是用户的每一条详细信息。通过仅提取应用界面中显示的列,您可以节省宝贵的资源,并且您的查询也能更快完成。

借助 Room,您可以从查询中返回任何基于 Java 的对象,前提是结果列集合会映射到返回的对象。例如,您可以创建以下基于 Java 的普通对象 (POJO) 来获取用户的名字和姓氏:

data class NameTuple(
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

现在,您可以在查询方法中使用此 POJO:

@Dao
interface MyDao {
    @Query("SELECT first_name, last_name FROM user")
    fun loadFullName(): List<NameTuple>
}

Room 知道该查询会返回 first_name 和 last_name 列的值,并且这些值会映射到 NameTuple 类的字段。因此,Room 可以生成正确的代码。如果查询返回太多的列,或者返回 NameTuple 类中不存在的列,则 Room 会显示一条警告。

使用RxJava进行响应式查询

dependencies {
    def room_version = "2.1.0"
    implementation 'androidx.room:room-rxjava2:$room_version'
}

Room 为 RxJava2 类型的返回值提供了以下支持: @Query 方法:Room 支持 Publisher、Flowable 和 Observable 类型的返回值。 @Insert、@Update 和 @Delete 方法:Room 2.1.0 及更高版本支持 Completable、Single 和 Maybe 类型的返回值。

@Dao
interface MyDao {
    @Query("SELECT * from user where id = :id LIMIT 1")
    fun loadUserById(id: Int): Flowable<User>

    // Emits the number of users added to the database.
    @Insert
    fun insertLargeNumberOfUsers(users: List<User>): Maybe<Int>

    // Makes sure that the operation finishes successfully.
    @Insert
    fun insertLargeNumberOfUsers(varargs users: User): Completable

    /* Emits the number of users removed from the database. Always emits at
     least one user. */
    @Delete
    fun deleteAllUsers(users: List<User>): Single<Int>
}

… …

这篇关于Android Room数据库(kotlin版)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!