Room 是 Android 官方的 SQLite 抽象层,提供编译时验证和流畅的 API。结合 Kotlin Flow,可以在 Compose 中实现响应式的数据库观察。
一、DAO with Flow
@Dao
interface ArticleDao {
// 返回 Flow,自动观察变化
@Query("SELECT * FROM articles ORDER BY published_at DESC")
fun getAllArticles(): Flow<List<ArticleEntity>>
@Query("SELECT * FROM articles WHERE id = :id")
fun getArticleById(id: String): Flow<ArticleEntity?>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(article: ArticleEntity)
}
二、ViewModel 集成
@HiltViewModel
class ArticleViewModel @Inject constructor(
private val repository: ArticleRepository
) : ViewModel() {
val articles: StateFlow<List<ArticleEntity>> = repository.allArticles
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
}
三、在 Compose 中使用
@Composable
fun ArticleListScreen(viewModel: ArticleViewModel = hiltViewModel()) {
val articles by viewModel.articles.collectAsState()
LazyColumn {
items(articles, key = { it.id }) { article ->
ArticleCard(article)
}
}
}
四、数据库迁移
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"ALTER TABLE articles ADD COLUMN category TEXT NOT NULL DEFAULT ''"
)
}
}
val database = Room.databaseBuilder(context, AppDatabase::class.java, "app.db")
.addMigrations(MIGRATION_1_2)
.build()
五、最佳实践
- ✅ DAO 返回 Flow 实现响应式观察
- ✅ 使用
stateIn转换为 StateFlow - ✅ Repository 层封装数据库操作
- ✅ 使用 Hilt 注入数据库依赖
- ✅ 实现迁移而非破坏性重建
- ✅ 使用内存数据库进行测试
总结
- Flow 返回值:自动观察变化
- stateIn:转换为 StateFlow
- Repository:封装数据访问
- Migration:保留用户数据