簡體   English   中英

Kotlin 房間數據庫 - 如何對列執行求和查詢?

[英]Kotlin Room Database - How to perform Sum Query on column?

我是 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()
    }
}

查看 Model:

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 中,您應該在viewModelScope中調用getTotalExpense()

堆棧跟蹤表明您正在主線程中進行查詢,您必須在后台線程中進行查詢,否則您必須使用以下代碼。

  private fun buildDatabase(context: Context) = Room.databaseBuilder(
        context.applicationContext,
        AppDatabase::class.java,
        DbConstants.APP_DB_NAME
    ).allowMainThreadQueries().fallbackToDestructiveMigration().build()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM