当前位置:网站首页>Use of jetpack's room in combination with flow
Use of jetpack's room in combination with flow
2022-06-29 23:35:00 【InfoQ】
preparation
RoomSQLiterely on
Roombuild.gradle dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
Main components
database: Include database holders , And as the main access point of the underlying connection of the application of the retained persistent relational data . Use@DatabaseAnnotated classes should meet the following conditions :
- It 's an extension
RoomDatabaseThe abstract class of .
- Add a list of entities associated with the database to the comment .
- Include with 0 And return to use
@DaoAbstract methods of annotated classes . At run time , You can callRoom.databaseBuilder()orRoom.inMemoryDatabaseBuilder()obtainDatabaseExample .
Entity: Represents a table in a database .
DAO: Contains methods for accessing the database .

Entity
@Entity(tableName = "t_history")
data class History(
/**
* @PrimaryKey Primary key ,autoGenerate = true Self increasing
* @ColumnInfo Column ,typeAffinity Field type
* @Ignore Ignore
*/
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
val id: Int? = null,
@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
val name: String?,
@ColumnInfo(name = "insert_time", typeAffinity = ColumnInfo.TEXT)
val insertTime: String?,
@ColumnInfo(name = "type", typeAffinity = ColumnInfo.INTEGER)
val type: Int = 1
)
- Entity Object corresponds to a table , Use
@Entityannotation , And declare your table name
@PrimaryKeyPrimary key ,autoGenerate = trueSelf increasing
@ColumnInfoColumn , And declare the listing ,typeAffinityField type
@IgnoreDeclare ignored objects
nameinsertTimeDAO
@Dao
interface HistoryDao {
// By type Query all search history
@Query("SELECT * FROM t_history WHERE type=:type")
fun getAll(type: Int = 1): Flow<List<History>>
@ExperimentalCoroutinesApi
fun getAllDistinctUntilChanged() = getAll().distinctUntilChanged()
// Add a search history
@Insert
fun insert(history: History)
// Delete a search history
@Delete
fun delete(history: History)
// Update a search history
@Update
fun update(history: History)
// according to id Delete a search history
@Query("DELETE FROM t_history WHERE id = :id")
fun deleteByID(id: Int)
// Delete all search history
@Query("DELETE FROM t_history")
fun deleteAll()
}
- @Insert: increase
- @Delete: Delete
- @Update: Change
- @Query: check
Query all search history Flowquery FlowFlow // By type Query all search history
@Query("SELECT * FROM t_history WHERE type=:type")
fun getAll(type: Int = 1): Flow<List<History>>
@ExperimentalCoroutinesApi
fun getAllDistinctUntilChanged() = getAll().distinctUntilChanged()
database
@Database(entities = [History::class], version = 1)
abstract class HistoryDatabase : RoomDatabase() {
abstract fun historyDao(): HistoryDao
companion object {
private const val DATABASE_NAME = "history.db"
private lateinit var mPersonDatabase: HistoryDatabase
// Be careful : If your application runs in a single process , In instantiation AppDatabase Object should follow the singleton design pattern .
// Every RoomDatabase The cost of an instance is quite high , You hardly need to access multiple instances in a single process
fun getInstance(context: Context): HistoryDatabase {
if (!this::mPersonDatabase.isInitialized) {
// Create an instance of the database
mPersonDatabase = Room.databaseBuilder(
context.applicationContext,
HistoryDatabase::class.java,
DATABASE_NAME
).build()
}
return mPersonDatabase
}
}
}
- Use
@DatabaseNote statement
entitiesArray , Corresponds to all tables in this database
versionDatabase version number
Singleton design pattern Use
mHistoryDao = HistoryDatabase.getInstance(this).historyDao()
Get search history
private fun getSearchHistory() {
MainScope().launch(Dispatchers.IO) {
mHistoryDao.getAll().collect {
withContext(Dispatchers.Main){
// to update ui
}
}
}
}
collectFlow coroutines UIpackage kotlinx.coroutines.flow
suspend Hang up coroutines @InternalCoroutinesApi
public suspend fun collect(collector: FlowCollector<T>)
Save search records
private fun saveSearchHistory(text: String) {
MainScope().launch(Dispatchers.IO) {
mHistoryDao.insert(History(null, text, DateUtils.longToString(System.currentTimeMillis())))
}
}
Clear local history
private fun cleanHistory() {
MainScope().launch(Dispatchers.IO) {
mHistoryDao.deleteAll()
}
}
Database upgrade
MigrationMigration newly added Definition Migration class
/**
* Database version 1->2 t_history The form added updateTime Column
*/
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE t_history ADD COLUMN updateTime String")
}
}
/**
* Database version 2->3 newly added label surface
*/
private val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `t_label` (`id` INTEGER PRIMARY KEY autoincrement, `name` TEXT)")
}
}
Migration- startVersion The old version
- endVersion The new version
Notify database update
mPersonDatabase = Room.databaseBuilder(
context.applicationContext,
HistoryDatabase::class.java,
DATABASE_NAME
).addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build()
Complete code
@Database(entities = [History::class, Label::class], version = 3)
abstract class HistoryDatabase : RoomDatabase() {
abstract fun historyDao(): HistoryDao
companion object {
private const val DATABASE_NAME = "history.db"
private lateinit var mPersonDatabase: HistoryDatabase
fun getInstance(context: Context): HistoryDatabase {
if (!this::mPersonDatabase.isInitialized) {
// Create an instance of the database
mPersonDatabase = Room.databaseBuilder(
context.applicationContext,
HistoryDatabase::class.java,
DATABASE_NAME
).addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build()
}
return mPersonDatabase
}
/**
* Database version 1->2 t_history The form added updateTime Column
*/
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE t_history ADD COLUMN updateTime String")
}
}
/**
* Database version 2->3 newly added label surface
*/
private val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `t_label` (`id` INTEGER PRIMARY KEY autoincrement, `name` TEXT)")
}
}
}
}
@Databaseentities It is recommended to upgrade the operation sequence
Configure compiler options
room.schemaLocation: Configure and enable the export of database schema to a given directory JSON File functionality . For details , see also Room transfer .
room.incremental: Enable Gradle Incremental annotation processor .
room.expandProjection: To configure Room To rewrite the query , Make its top star projection contain only DAO Method returns the column defined in the type .
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation":"$projectDir/schemas".toString(),
"room.incremental":"true",
"room.expandProjection":"true"]
}
}
}
}
schemasjson{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "xxx",
"entities": [
{
"tableName": "t_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `insert_time` TEXT, `type` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "insertTime",
"columnName": "insert_time",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'xxx')"
]
}
}
Reference resources
- Room Official documents
- Room Update log
- Flow Official documents
- actual combat | stay Room Use in Flow
- coroutines Flow Best practices | be based on Android Developer summit applications
边栏推荐
- C pointer advanced 2-- > function pointer array callback function simplifies calculator code, and implements qsort function based on callback function simulation
- 111.简易聊天室14:聊天室客户端
- 优雅的改造短信业务模块,策略模式走起!
- Matplotlib plt Hist() parameter explanation
- 2022年PMP项目管理考试敏捷知识点(5)
- Solr基础操作5
- 记一次排查线上MySQL死锁过程,不能只会curd,还要知道加锁原理
- Solr基础操作1
- Redis client
- Leetcode(76)——最小覆盖子串
猜你喜欢

正则表达式:字符(2)

sql刷题595. 大的国家

论文阅读《Large-Scale Direct SLAM with Stereo Cameras》

疫情下我离职一年,收入增长了10倍

海外数字身份验证服务商ADVANCE.AI入选EqualOcean《2022品牌出海服务市场研究报告》

众昂矿业:萤石助力氟产业锂电建设发展

Matplotlib histogram of Matplotlib visualization plt bar()

新钛云服荣膺“2022爱分析 · IT运维厂商全景报告”云管理平台CMP 代表厂商!...

High performance and high availability computing architecture of "microblog comments" in microblog system

2022年PMP项目管理考试敏捷知识点(5)
随机推荐
MetaQ集群安装测试
Discussion on distributed unique ID generation scheme
LC:有效的数独 + 旋转图像
@Scheduled注解的坑,我替你踩了
疫情下我离职一年,收入增长了10倍
[从零开始学习FPGA编程-51]:高阶篇 - 基于IP核的FPGA开发- 什么是FPGA IP核(软核、固核、硬核)与学习方法
Overseas digital authentication service provider advance AI was selected into the "2022 brand sea Service Market Research Report" of equalocean
Implementation principle of dynamic agent
Sword finger offer 38 Arrangement of strings
C指针进阶1-->字符指针,数组指针,指针与数组传参,函数指针
Leetcode 1385. Distance value between two arrays
Jetpack之Room的使用,结合Flow
关于二叉树
数据库-玩转数据-Pgsql 使用UUID做主键
为什么 JSX 语法这么香?
基于OpenStack的虚拟机在线迁移
Pain points and solutions of M1 notebook home office | community essay solicitation
Error: c2665: "qmessagebox:: critical": none of the four overloads can convert all parameter types
Test d'installation du cluster metaq
微博系统中”微博评论“的高性能高可用计算架构