android - Kotlin Room Database - 如何对列执行求和查询?
问题描述
我是 Kotlin 和 Android 编程的新手。我需要一些关于我的代码的帮助。我正在尝试对我的房间数据库中的列执行 SUM 查询,到目前为止它给我带来了麻烦。我试图让值返回为 Double 并且应用程序每次都会崩溃。列,expenseAmount 是一个 Double 类型的列。
这是我到目前为止所拥有的:
道:
@Dao
interface ExpenseDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addExpense(expense: Expense)
@Query("SELECT * FROM ExpenseListTable ORDER BY id ASC")
fun readAllExpenseData(): LiveData<List<Expense>>
@Delete
suspend fun deleteExpense(expense: Expense)
@Query("SELECT SUM(expenseAmount) FROM ExpenseListTable")
fun getTotalExpense():Double
}
存储库:
class ExpenseRepository(private val expenseDao: ExpenseDao) {
val readAllData:LiveData<List<Expense>> = expenseDao.readAllExpenseData()
suspend fun addExpense(expense: Expense){
expenseDao.addExpense(expense)
}
suspend fun deleteExpense(expense: Expense){
expenseDao.deleteExpense(expense)
}
fun getTotal(): Double {
return expenseDao.getTotalExpense()
}
}
查看型号:
class ExpenseViewModel(application: Application): AndroidViewModel(application) {
val readAllExpenseData: LiveData<List<Expense>>
private val repository: ExpenseRepository
init {
val expenseDao = ExpenseDatabase.getDatabase(application).ExpenseDao()
repository = ExpenseRepository(expenseDao)
readAllExpenseData = repository.readAllData
}
fun addExpense(expense: Expense){
viewModelScope.launch(Dispatchers.IO) {
repository.addExpense(expense)
}
}
fun deleteExpense(expense: Expense){
viewModelScope.launch(Dispatchers.IO) {
repository.deleteExpense(expense)}
}
fun getTotalExpense():Double{
return repository.getTotal()
}
}
活动.kt
val sum = mExpenseViewModel.getTotalExpense()
这是错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.momoney101/com.android.momoney101.ExpenseList}: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267)
at androidx.room.RoomDatabase.query(RoomDatabase.java:323)
at androidx.room.util.DBUtil.query(DBUtil.java:83)
at com.android.momoney101.data.ExpenseDao_Impl.getTotalExpense(ExpenseDao_Impl.java:157)
at com.android.momoney101.repository.ExpenseRepository.getTotal(ExpenseRepository.kt:27)
at com.android.momoney101.viewmodel.ExpenseViewModel.getTotalExpense(ExpenseViewModel.kt:61)
at com.android.momoney101.ExpenseList.onCreate(ExpenseList.kt:69)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我对下一步该做什么有点困惑。感谢您的时间。
解决方案
在您的 ViewModel 中,您应该getTotalExpense()
在viewModelScope
推荐阅读
- google-bigquery - 更改 Google Big Query 上的数据类型:日期字段错误
- azure - 应用服务部署卡住加载 - 我们如何解决?
- javascript - React UseEffect 卸载组件
- ffmpeg - 没有这样的过滤器 - 初始化复杂过滤器时出错 - 参数无效
- python - 在参数化中传递 pytest 夹具
- javascript - 加载多个脚本后的回调函数
- php - 使用 PHPMailer 发送电子邮件
- c# - CefSharp 共享会话 Cookies c#
- c++ - 如何在 c++20 约束算法中嵌套投影元素?
- typescript - Typescript - 类型函数,返回作为参数传递的每个函数的返回值的 UNION