1、前语
上一篇5分钟带你了解Android Room数据好起来了,有人催更,遂决定再写一篇Room的运用,这篇咱们着重讲讲注解。假如写的欠好,或者有错误之处,恳请在谈论、私信、邮箱指出,万分感谢
2、@ForeignKey和@PrimaryKey
检测你数据库常识的时分来了!由于你会频繁看到@PrimaryKey
所以先讲它
@ForeignKey
注解用于界说外键联系,它指定了一个实体类中的一个字段是另一个实体类的主键。这种联系被称为“外键联系”,而且能够用于在多个表之间树立相关。
例如,假如有两个实体类 User
和 Address
,而且想要将它们相关起来,则能够运用 @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
,不同的位置形成的影响也是不同的,实际上能够应用到以下四个当地:
- 实体类:在
@Entity
注解中运用,能够在处理该实体类时运用它们。 - DAO 接口:在 DAO 接口中运用,能够在履行该 DAO 中的查询时运用它们。
- 数据库类:在
RoomDatabase
类中运用, 能够在整个数据库中运用它们。 - 实体类中的特点:在实体类中的特点,能够在处理该特点时运用指定的类型转化器
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>
)
在这个示例中,咱们有两个实体类 User
和 Book
,它们之间有一个父子联系,其间一个用户能够具有多本书。然后,咱们界说了一个 UserWithBooks
数据类,它包括一个嵌套的 User
实体和一个 @Relation
注解,用于指定怎么检索与该用户相关的一切书本。@Relation
注解包括 parentColumn
和 entityColumn
参数,别离指定父实体的主键列和子实体的外键列。
当咱们运用 @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
)
在这个比如中,咱们运用 @Ignore
将 password
字段指定为应该被疏忽的字段。这意味着在数据库表中,这个字段将不会出现,也不会被映射到 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) {
// ...
}
}
在这个比如中,咱们运用 @Ignore
将 setPassword
办法指定为应该被疏忽的办法。这意味着 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
注解在 name
和 age
字段上创立了两个索引。这将使数据库系统能够更快地查找和排序 User
表中的数据。
(3)在一个实体类中创立复合索引
@Index
注解还能够用于在一个实体类中创立复合索引。复合索引是指将多个字段组合在一同以创立一个索引,这将使数据库系统能够更快地查找和排序这些字段的组合。
例如,假如期望在 User
表中依照 name
和 age
字段的组合进行排序,则能够运用 @Index
注解来创立一个复合索引:
@Entity(tableName = "users", indices = [
Index(value = ["name", "age"])
])
data class User(
@PrimaryKey val id: Int,
val name: String,
val age: Int
)
在这个比如中,咱们运用 @Index
注解在 name
和 age
字段上创立了一个复合索引。这将使数据库系统能够更快地查找和排序 User
表中依照 name
和 age
字段的组合进行排序的数据。
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
注解指定了包括 User
和 Address
实体类的数据库版本号。然后,咱们界说了两个笼统办法 userDao()
和 addressDao()
,别离用于回来 UserDao
和 AddressDao
数据拜访目标 (DAO)。
(3)指定数据库晋级战略
最终,@Database
注解还能够用于指定数据库晋级战略。当晋级数据库时,或许需求指定一些操作来处理数据模式的变化。Room 提供了两种晋级战略:Migrate
和 FallbackToDestructiveMigration
。
例如,假如期望在晋级数据库时保留现有数据,能够运用 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
的虚拟表。该表将根据 title
、author
和 description
列的内容创立一个全文本索引。当您履行全文本查找时,将运用该索引来查找与查找查询匹配的行。
(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
的虚拟表。该表将根据 title
、author
和 description
列的内容创立一个全文本索引。与 @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、感谢
- 校稿:ChatGpt/Bing
- 文笔优化:ChatGpt/Bing/秘塔写作猫
“敞开生长之旅!这是我参加「日新计划 2 月更文挑战」的第 8 天,点击查看活动详情”