1、前语

上一篇5分钟带你了解Android Room数据好起来了,有人催更,遂决定再写一篇Room的运用,这篇咱们着重讲讲注解。假如写的欠好,或者有错误之处,恳请在谈论、私信、邮箱指出,万分感谢

2、@ForeignKey和@PrimaryKey

检测你数据库常识的时分来了!由于你会频繁看到@PrimaryKey所以先讲它

@ForeignKey 注解用于界说外键联系,它指定了一个实体类中的一个字段是另一个实体类的主键。这种联系被称为“外键联系”,而且能够用于在多个表之间树立相关。

例如,假如有两个实体类 UserAddress,而且想要将它们相关起来,则能够运用 @ForeignKey 注解来指定 Address 中的 user_id 字段是 User 的主键:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String
)
@Entity(tableName = "addresses",
        foreignKeys = [
            ForeignKey(entity = User::class,
                       parentColumns = ["id"],
                       childColumns = ["user_id"],
                       onDelete = ForeignKey.CASCADE)
        ])
data class Address(
    @PrimaryKey val id: Int,
    val street: String,
    val city: String,
    val state: String,
    val zip: String,
    @ColumnInfo(name = "user_id") val userId: Int
)

在这个比如中,咱们运用 @ForeignKey 注解将 Address 中的 user_id 字段指定为 User 的主键。这将创立一个外键联系,保证在刺进或更新 Address 表中的数据时,user_id 字段的值有必要是 User 表中存在的主键值之一。

@PrimaryKey 注解用于指定实体类中的一个字段是主键。主键是用于仅有标识每个实体类目标的字段。在 Room 中,每个实体类有必要至少有一个字段被指定为主键。

例如,假如有一个实体类 User,而且想要将 id 字段指定为主键,则能够运用 @PrimaryKey 注解:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String
)

在这个比如中,咱们运用 @PrimaryKey 注解将 id 字段指定为 User 实体类的主键。这将保证在刺进或更新 User 表中的数据时,每个 id 字段的值都是仅有的。

3、@TypeConverters

在运用Room时,你或许会遇到需求在Entity类中运用非根本类型的状况,例如Date、Calendar、List等类型。在这种状况下,你能够运用TypeConverters将这些类型转化为Room能够存储的类型。在Room中,能够运用@TypeConverter注解来界说一个类型转化器,例如:

class Converters {
    @TypeConverter
    fun fromDate(date: Date): Long {
        return date.time
    }
    @TypeConverter
    fun toDate(timestamp: Long): Date {
        return Date(timestamp)
    }
    @TypeConverter
    fun fromList(list: List<String>?): String? {
        return list?.joinToString(",")
    }
    @TypeConverter
    fun toList(string: String?): List<String>? {
        return string?.split(",")
    }
}
@Entity(tableName = "user")
@TypeConverters(Converters::class)
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val birthday: Date
  	@TypeConverters(HobbiesConverter::class) val hobbies: List<String>
)
@Database(entities = [User::class], version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
    // ...
}
@Dao
@TypeConverters(Converters::class)
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>
}

示例代码在十分多的当地运用了@TypeConverters ,不同的位置形成的影响也是不同的,实际上能够应用到以下四个当地:

  1. 实体类:在 @Entity 注解中运用,能够在处理该实体类时运用它们。
  2. DAO 接口:在 DAO 接口中运用,能够在履行该 DAO 中的查询时运用它们。
  3. 数据库类:在 RoomDatabase 类中运用, 能够在整个数据库中运用它们。
  4. 实体类中的特点:在实体类中的特点,能够在处理该特点时运用指定的类型转化器

4、@Relation

@Relation 用于在实体类之间树立联系。它能够用于界说两个或更多实体之间的联系,这些实体能够在数据库中别离存储在不同的表中。

@Relation 注解应该与 @Query 注解一同运用,以便 Room 能够在查询结果中回来相关实体之间的联系。@Relation 注解的一个常见用例是界说父子联系,其间一个实体包括对另一个实体的引用。

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val email: String
)
@Entity(tableName = "books")
data class Book(
    @PrimaryKey val id: Int,
    val title: String,
    val author: String,
    val userId: Int
)
data class UserWithBooks(
    @Embedded val user: User,
    @Relation(
        parentColumn = "id",
        entityColumn = "userId"
    )
    val books: List<Book>
)

在这个示例中,咱们有两个实体类 UserBook,它们之间有一个父子联系,其间一个用户能够具有多本书。然后,咱们界说了一个 UserWithBooks 数据类,它包括一个嵌套的 User 实体和一个 @Relation 注解,用于指定怎么检索与该用户相关的一切书本。@Relation 注解包括 parentColumnentityColumn 参数,别离指定父实体的主键列和子实体的外键列。

当咱们运用 @Relation 注解时,咱们需求在查询中运用 SELECT 句子,以便 Room 能够检索相关的实体。例如,在 Dao 接口中,咱们能够运用以下查询:

//Transaction下一点就会说
@Transaction
@Query("SELECT * FROM users WHERE id = :id")
fun getUserWithBooks(id: Int): UserWithBooks

此外,咱们运用 SELECT * 句子来检索一切用户特点和相关的书本列表,由于 UserWithBooks 数据类包括一个嵌套的 User 实体和一个 List<Book> 列表。

5、@Transaction

第4点说到@Relation时运用到了@Transaction。在这个查询中,咱们运用 @Transaction 注解来保证整个查询作为一个业务履行,以便 Room 能够在单个操作中检索 User 实体和与之相关的一切 Book 实体。

@Transaction用于将一组数据库操作包装在一个业务中。它能够保证在履行数据库操作时坚持数据库的一致性,并在必要时回滚业务以保证数据的完整性。

在 Room 中,单个数据库操作(例如刺进、更新或删去)是主动运行在业务中的。但是,当需求履行多个数据库操作时,或许需求手动创立一个业务来保证这些操作原子性地履行。假如需求履行多个数据库操作,请始终考虑运用 @Transaction 注解。这能够防止数据不一致和其他与数据库操作相关的问题。

6、@Embedded

上一篇,有同志说@Embedded很好用,确实如此哈

@Embedded用于指定一个实体类中的一个或多个字段应该作为其所属的另一个实体的嵌入式目标。这使得 Room 能够将多个相关实体的数据组合成一个独自的目标,从而简化了数据库操作。

当在一个实体类中运用 @Embedded 注解时,能够指定该实体类中的一个或多个字段应该嵌入到另一个实体类中。例如,假设有一个 Address 实体类和一个 User 实体类,其间 User 实体类包括一个 Address 目标。能够运用 @Embedded 注解将 Address 目标嵌入到 User 实体类中:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    @Embedded val address: Address
)
data class Address(
    val street: String,
    val city: String,
    val state: String,
    val zip: String
)

在这个比如中,User 实体类包括一个 Address 目标,它运用 @Embedded 注解指定了该目标应该嵌入到 User 实体类中。在查询数据库时,Room 将主动组合 User 实体类和 Address 实体类中的字段,以便能够轻松地拜访和操作它们。

还能够运用 prefix 参数来指定 Room 应该在组合两个实体类中的字段时运用的前缀。例如:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    @Embedded(prefix = "home_") val homeAddress: Address,
    @Embedded(prefix = "work_") val workAddress: Address
)

在这个比如中,User 实体类包括两个 Address 目标,一个是 homeAddress,另一个是 workAddress。咱们运用 @Embedded(prefix = "home_")@Embedded(prefix = "work_") 注解为每个地址目标指定了不同的前缀。这使得 Room 能够区别两个地址目标中的相同字段,并将它们组合成一个独自的目标。

当然你也能够这么干

@Entity(tableName
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    @Embedded @ColumnInfo(name = "home_address") val homeAddress: Address
)

7、@ColumnInfo

能够看到,咱们刚刚用到了@ColumnInfo这个注解,用于自界说实体类中的列名、默认值和其他特点。当需求将一个实体类映射到数据库表时,能够运用 @ColumnInfo 注解来指定实体类中的每个字段在数据库表中的称号和其他特点。

(1)指定实体类中的字段称号

@ColumnInfo 注解最常用的用处是指定实体类中的字段称号。例如:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "full_name") val name: String,
    val age: Int
)

在这个比如中,咱们运用 @ColumnInfo(name = "full_name")name 字段的称号指定为 full_name。这意味着在数据库表中,这个字段将被命名为 full_name,而不是 name

(2)指定实体类中的字段默认值

@ColumnInfo 注解还能够用于指定实体类中的字段默认值。例如:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "full_name") val name: String,
    @ColumnInfo(name = "is_active") val isActive: Boolean = true
)

在这个比如中,咱们运用 @ColumnInfo(name = "is_active")isActive 字段的称号指定为 is_active,并将其默认值设置为 true。这意味着在数据库表中,这个字段将被命名为 is_active,而且默认值将为 true

(3)指定实体类中的字段束缚

@ColumnInfo 注解还能够用于指定实体类中的字段束缚。例如:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "full_name") val name: String,
    @ColumnInfo(name = "is_active") val isActive: Boolean = true,
    @ColumnInfo(name = "created_at", defaultValue = "CURRENT_TIMESTAMP") val createdAt: String
)

在这个比如中,咱们运用 @ColumnInfo(name = "created_at", defaultValue = "CURRENT_TIMESTAMP")createdAt 字段的称号指定为 created_at,并将其默认值设置为 CURRENT_TIMESTAMP。这意味着在数据库表中,这个字段将被命名为 created_at,而且默认值将为 CURRENT_TIMESTAMP

8、@Ignore

很直观的注解哈。指定实体类中应该疏忽的字段。当需求在实体类中增加一个字段,但不想将其映射到数据库表中时,能够运用 @Ignore 注解来指定该字段应该被疏忽。

疏忽一个实体类中的字段

@Ignore 注解最常用的用法是疏忽一个实体类中的字段,从而防止该字段被映射到数据库表中。例如:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    @Ignore val password: String
)

在这个比如中,咱们运用 @Ignorepassword 字段指定为应该被疏忽的字段。这意味着在数据库表中,这个字段将不会出现,也不会被映射到 User 实体类中。

(1)疏忽一个实体类中的 getter 和 setter 办法

除了疏忽一个实体类中的字段外,@Ignore 注解还能够用于疏忽一个实体类中的 getter 和 setter 办法。这能够协助操控 Room 怎么处理实体类中的办法。

例如,假如期望 Room 不生成一个实体类中的 setter 办法,则能够将 @Ignore 注解增加到该办法上:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val password: String
) {
    @Ignore
    fun setPassword(password: String) {
        // ...
    }
}

在这个比如中,咱们运用 @IgnoresetPassword 办法指定为应该被疏忽的办法。这意味着 Room 不会生成一个 setter 办法来设置 password 字段的值。

(2)疏忽一个实体类中的整个结构函数

最终,@Ignore 注解还能够用于疏忽一个实体类中的整个结构函数。这能够协助操控 Room 怎么处理实体类中的结构函数。

例如,假如期望 Room 不运用默认的结构函数来创立实体类的实例,则能够运用 @Ignore 注解符号该结构函数:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val password: String
) {
    @Ignore
    constructor(id: Int, name: String) : this(id, name, "")
}

在这个比如中,咱们运用 @Ignore 将第二个结构函数指定为应该被疏忽的结构函数。这意味着 Room 不会运用这个结构函数来创立 User 实体类的实例。

9、@Index

检测你数据库常识的时分来了!索引(个索引、多个索引、复合索引)能够进步数据库表查询的功能,由于它们使数据库系统能够更快地查找和排序表中的数据。

(1)在一个实体类中创立单个索引

@Index 注解最常用的用法是在一个实体类中创立单个索引。例如:

@Entity(tableName = "users", indices = [Index(value = ["name"])])
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val age: Int
)

在这个比如中,咱们运用 @Index 注解在 name 字段上创立了一个单个索引。这将使数据库系统能够更快地查找和排序 User 表中的数据。

(2)在一个实体类中创立多个索引

除了在一个实体类中创立单个索引外,@Index 注解还能够用于在一个实体类中创立多个索引。例如:

@Entity(tableName = "users", indices = [
    Index(value = ["name"]),
    Index(value = ["age"])
])
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val age: Int
)

在这个比如中,咱们运用 @Index 注解在 nameage 字段上创立了两个索引。这将使数据库系统能够更快地查找和排序 User 表中的数据。

(3)在一个实体类中创立复合索引

@Index 注解还能够用于在一个实体类中创立复合索引。复合索引是指将多个字段组合在一同以创立一个索引,这将使数据库系统能够更快地查找和排序这些字段的组合。

例如,假如期望在 User 表中依照 nameage 字段的组合进行排序,则能够运用 @Index 注解来创立一个复合索引:

@Entity(tableName = "users", indices = [
    Index(value = ["name", "age"])
])
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val age: Int
)

在这个比如中,咱们运用 @Index 注解在 nameage 字段上创立了一个复合索引。这将使数据库系统能够更快地查找和排序 User 表中依照 nameage 字段的组合进行排序的数据。

10、@Entity

当在 Room 中界说一个实体类时,有必要运用 @Entity 注解来指定该类应该被映射到数据库中的哪个表。

(1)在一个实体类中指定表名

@Entity 注解最常用的用法是在一个实体类中指定表名。例如:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val age: Int
)

在这个比如中,咱们运用 @Entity 注解将 User 实体类映射到名为 users 的数据库表中。这将使 Room 能够将 User 类中的字段映射到数据库表中的相应列中。

(2)在一个实体类中指定索引

除了在一个实体类中指定表名外,@Entity 注解还能够用于在一个实体类中指定索引。索引能够进步数据库表查询的功能,由于它们使数据库系统能够更快地查找和排序表中的数据。

例如,假如期望在 User 表中依照 name 字段进行排序,则能够运用 @Entity 注解来创立一个索引:

@Entity(tableName = "users", indices = [Index(value = ["name"])])
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val age: Int
)

在这个比如中,咱们运用 @Entity 注解在 name 字段上创立了一个索引。这将使数据库系统能够更快地查找和排序 User 表中的数据。

(3)在一个实体类中指定承继联系

最终,@Entity 注解还能够用于在一个实体类中指定承继联系。假如的实体类承继自另一个实体类,则能够运用 @Entity 注解来指定它们之间的联系。

例如,假如有一个 Person 实体类和一个 Employee 实体类,Employee 实体类承继自 Person 实体类,则能够运用 @Entity 注解来指定它们之间的联系:

@Entity(tableName = "user")
open class User(
    @PrimaryKey val id: Int,
    val name: String
)
@Entity(tableName = "employees")
data class Employee(
    @PrimaryKey val id: Int,
    val salary: Int,
    @ColumnInfo(name = "user_id") val userId: Int
) : User(userId, "")

在这个比如中,咱们运用 @Entity 注解将 Person 实体类映射到名为 people 的数据库表中,并将 Employee 实体类映射到名为 employees 的数据库表中。此外,咱们还运用 @Entity 注解指定了 Employee 实体类承继自 Person 实体类,并运用 @ColumnInfo 注解将 person_id 字段指定为 Employee 表中的外键。这将保证在刺进或更新 Employee 表中的数据时,person_id 字段的值有必要是 Person 表中存在的主键值之一。

11、@Dao

@Dao 是用于拜访数据库中数据的一种笼统层。在 Room 中,每个 DAO 都界说了一组用于与数据库进行交互的办法。意思是就这么用,没啦。

@Dao
interface UserDao {}

12、@Database

@Database 注解是 Room 中的一个注解,用于界说数据库类。当在 Room 中界说一个数据库时,有必要运用 @Database 注解来指定该数据库包括哪些实体类和版本号等信息。

(1)在一个类中界说数据库实例

@Database 注解最常用的用法是在一个类中界说数据库实例。例如:

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

在这个比如中,咱们运用 @Database 注解界说了一个数据库类 AppDatabase,并在其间指定了包括 User 实体类的数据库版本号。此外,咱们还界说了一个笼统办法 userDao(),用于回来一个 UserDao 数据拜访目标 (DAO)。

(2)指定多个实体类

@Database 注解还能够用于指定多个实体类。例如:

@Database(entities = [User::class, Address::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
    abstract fun addressDao(): AddressDao
}

在这个比如中,咱们运用 @Database 注解指定了包括 UserAddress 实体类的数据库版本号。然后,咱们界说了两个笼统办法 userDao()addressDao(),别离用于回来 UserDaoAddressDao 数据拜访目标 (DAO)。

(3)指定数据库晋级战略

最终,@Database 注解还能够用于指定数据库晋级战略。当晋级数据库时,或许需求指定一些操作来处理数据模式的变化。Room 提供了两种晋级战略:MigrateFallbackToDestructiveMigration

例如,假如期望在晋级数据库时保留现有数据,能够运用 Migrate 晋级战略:

val migration1to2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        // TODO: write migration code here
    }
}
@Database(entities = [User::class], version = 2, migrations = [migration1to2])
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

在这个比如中,咱们运用 Migrate 晋级战略将数据库版本从 1 晋级到 2。咱们界说了一个名为 migration1to2 的迁移目标,用于在晋级数据库时履行自界说的 SQL 句子。然后,咱们运用 @Database 注解指定了包括 User 实体类的数据库版本号和晋级战略。

假如不需求保留现有数据,能够运用 FallbackToDestructiveMigration 晋级战略:

@Database(entities = [User::class], version = 2, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
    companion object {
        @Volatile
        private var instance: AppDatabase? = null
        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }
        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, "app-database")
                .fallbackToDestructiveMigration().build()
        }
    }
}

在这个比如中,咱们运用 FallbackToDestructiveMigration 晋级战略将数据库版本从 1 晋级到 2。咱们运用 @Database 注解指定了包括 User 实体类的数据库版本号和晋级战略,并将 exportSchema 参数设置为 false,以防止生成不必要的 JSON 文件。

13、@Query

用于界说SQL查询句子,能够在之前的比如中找到,许多的@Query的身影 (检测你数据库基础的时分到了!)

(1)根本查询操作

@Query 注解最常用的用法是履行根本的查询操作。例如:

@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    fun getAllUsers(): List<User>
}

在这个比如中,咱们运用 @Query 注解界说了一个根本的 SQL 查询句子,该句子将回来 users 表中的一切数据。咱们将此查询界说为 getAllUsers() 办法的一部分,以便在需求时调用该办法。

(2)带参数的查询操作

@Query 注解还能够用于履行带参数的查询操作。例如:

@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :id")
    fun getUserById(id: Int): User
}

在这个比如中,咱们运用 @Query 注解界说了一个带有参数的 SQL 查询句子,该句子将回来 users 表中 id 字段等于给定值的数据。咱们将此查询界说为 getUserById() 办法的一部分,并将 id 参数传递给查询句子。

(3)运用相关查询

最终,@Query 注解还能够用于履行相关查询。相关查询是一种能够跨多个表查询数据的查询类型。

@Dao
interface UserDao {
    @Query("SELECT * FROM users INNER JOIN addresses ON users.address_id = addresses.id")
    fun getUsersWithAddresses(): List<UserWithAddress>
}

在这个比如中,咱们运用 @Query 注解界说了一个相关查询句子,该句子将回来 users 表中的数据以及与之相关的 addresses 表中的数据。咱们将此查询界说为 getUsersWithAddresses() 办法的一部分,并运用 INNER JOIN 子句指定 users 表和 addresses 表之间的联系。

14、@Insert、@Update、@Delete

顾名思义哈,也就不用举例了,嘻嘻嘻

@Dao
interface UserDao {
    @Insert\@Update\@Delete
    fun xxxUser(user: User)
}

15、多数据源

运用Kotlin Flow能够很方便地处理多个数据源的状况。在运用Room时,咱们能够在Repository层中完成本地和长途数据源的逻辑,并运用Kotlin Flow来组合和转化数据。

以下是一个示例,演示了怎么运用Room和Kotlin Flow处理多个数据源的状况:

class UserRepository(
    private val userDao: UserDao,
    private val api: ApiService
) {
    fun getUsers(): Flow<List<User>> {
        val localUsers = userDao.getAll().asFlow()
        val remoteUsers = api.getUsers().asFlow()
        return localUsers.combine(remoteUsers) { local, remote ->
            // 兼并本地和长途数据
            (local + remote).distinctBy { it.id }
        }
    }
    suspend fun updateUser(user: User) {
        api.updateUser(user.id, user)
        userDao.update(user)
    }
}

在以上示例中,咱们在UserRepository中运用了本地和长途数据源,并运用Kotlin Flow.combine操作符将本地和长途数据源兼并在一同,并在最终回来一个Flow目标。咱们还运用了suspend修饰符将updateUser办法符号为挂起函数,以便能够在协程中履行异步操作。

很方便吧

16、@Fts3和@Fts4

这个一般用不到来着,不过假如你要做小说软件的话,或许有用。用于创立全文本查找虚拟表。全文本查找是一种在大型文本数据集中查找特定文本片段的技术。当您需求在应用程序中完成全文本查找时,能够运用这两个注解来创立虚拟表。

(1)@Fts3 注解

@Fts3 注解用于创立一个根据 SQLite FTS3 算法的虚拟表。例如:

@Fts3
@Entity(tableName = "books")
data class Book(
    @ColumnInfo(name = "book_title") val title: String,
    @ColumnInfo(name = "book_author") val author: String,
    @ColumnInfo(name = "book_description") val description: String
)

在这个比如中,咱们运用 @Fts3 注解界说了一个名为 books 的虚拟表。该表将根据 titleauthordescription 列的内容创立一个全文本索引。当您履行全文本查找时,将运用该索引来查找与查找查询匹配的行。

(2)@Fts4 注解

@Fts4 注解用于创立一个根据 SQLite FTS4 算法的虚拟表。例如:

@Fts4(contentEntity = Book::class)
@Entity(tableName = "book_fts")
data class BookFts(
    @ColumnInfo(name = "book_fts_title") val title: String,
    @ColumnInfo(name = "book_fts_author") val author: String,
    @ColumnInfo(name = "book_fts_description") val description: String
)

在这个比如中,咱们运用 @Fts4 注解界说了一个名为 book_fts 的虚拟表。该表将根据 titleauthordescription 列的内容创立一个全文本索引。与 @Fts3 注解不同的是,@Fts4 注解需求运用 contentEntity 参数指定要创立索引的实体类。

(3)运用全文本查找

创立全文本查找虚拟表后,您能够运用 Room 中的 MATCH 关键字来履行全文本查找。例如:

@Dao
interface BookDao {
    @Query("SELECT * FROM books WHERE books MATCH :query")
    fun searchBooks(query: String): List<Book>
}

在这个比如中,咱们运用 MATCH 关键字来履行全文本查找操作。该操作将在 books 虚拟表中查找与 query 参数匹配的行,并回来一切匹配的结果。留意,在运用这些注解时,请保证为要查找的列创立了索引,以防止查找操作变得缓慢或不可用。

17、总结

咱们在这一篇提到了17个注释,,咱们能够运用以上注解来界说实体类、DAO接口和数据库,并完成各种数据操作和类型转化。这些注解能够协助咱们更好地运用Room进行开发,并完成愈加杂乱和高效的功能,涵盖了绝大数开发的需求。当然,在实际开发中,咱们还需求根据详细的业务需求和技术特点来选择适宜的计划和完成方法。

实际上,Room的应用远不止如此,假如有人感兴趣的话,我就持续出下一期吧!

13、感谢

  1. 校稿:ChatGpt/Bing
  2. 文笔优化:ChatGpt/Bing/秘塔写作猫

“敞开生长之旅!这是我参加「日新计划 2 月更文挑战」的第 8 天,点击查看活动详情”