You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库插入新行时返回rowId的实现问题及解决方案

问题描述

我查阅Android官方文档得知:

若@Insert方法接收单个参数,可返回long类型值,即插入项的新rowId。

这正是我需要的功能:插入新行后返回新rowId并在Activity中使用,但当前结合suspend函数的架构无法实现该功能。以下是我的原有代码结构:


原有代码结构

Room 实体类

@Entity(
    tableName = "note_table",
    indices = [Index(
        value = ["db_key"],
        unique = true
    )]
)
data class NoteEntity(
    ...
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "db_key")
    val uid: Long? = null
)

Dao 接口

@Dao
interface NoteEntityDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertNote(note: Note)
    ...
}

Repository 接口

interface NoteRepository {

    suspend fun insertNote(note: Note)
    ...
}

Repository 实现类

class NoteRepositoryImplementation @Inject constructor(
    private val dao: NoteEntityDao
) : NoteRepository {

    override suspend fun insertNote(note: NoteEntity) {
        dao.insertNoteEntry(note)
    }

Use Case 类

class AddNoteUseCase(
    private val repository: NoteRepository
) {

    suspend fun execute(note: Note) {
        repository.insertNote(note)
    }
}

ViewModel 类

@HiltViewModel
class NoteViewModel @Inject constructor(
    private val noteUseCases: NoteUseCases
) : ViewModel() {

    fun insertNote(note: NoteEntity) {
        viewModelScope.launch {
            noteUseCases.addNoteUseCase.execute(note)
        }
    }

Activity 代码

class NoteActivity : AppCompatActivity() {
...
val newNoteEntry = NoteEntity(
                    title = title,
                    description = description,
                    createdOn = createdOn,
                    createdBy = createdBy
                )

viewModel.insertNote(newNoteEntry)
...
}

解决方案(由Tenfour04提供)

Dao 接口修改

@Dao
interface NoteEntityDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertNote(note: Note): Long
    ...
}

Repository 接口修改

interface NoteRepository {

    suspend fun insertNote(note: Note): Long
    ...
}

Repository 实现类修改

class NoteRepositoryImplementation @Inject constructor(
    private val dao: NoteEntityDao
) : NoteRepository {

    override suspend fun insertNote(note: NoteEntity): Long {
        return dao.insertNoteEntry(note)
    }
...
}

Use Case 类修改

class AddNoteUseCase(
    private val repository: NoteRepository
) {

    suspend fun execute(note: Note): Long {
        return repository.insertNote(note)
    }
}

ViewModel 类修改

@HiltViewModel
class NoteViewModel @Inject constructor(
    private val noteUseCases: NoteUseCases
) : ViewModel() {

    suspend fun insertNote(note: NoteEntity): Long {
        viewModelScope.launch {
            return noteUseCases.addNoteUseCase.execute(note)
        }
    }
...
}

Activity 代码修改

class NoteActivity : AppCompatActivity() {
...
val newNoteEntry = NoteEntity(
                    title = title,
                    description = description,
                    createdOn = createdOn,
                    createdBy = createdBy
                )

lifecycleScope.launchWhenStarted {
                    val foo = viewModel.insertNote(newNoteEntry)
                    Log.d(TAG, "newRowId: $foo")
                }
...
}

Logcat 输出

Logcat输出


内容的提问来源于stack exchange,提问作者Maarten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:30:26