Android Room - вставка работает, но select не возвращает никаких значений - PullRequest
0 голосов
/ 10 июля 2019

Я хочу выбрать данные из базы данных через комнату.

Вот мой код.

База данных

@Database(entities = [TicketDb::class], version = 1)
@TypeConverters(DatabaseConverters::class)
abstract class MyDatabase : RoomDatabase() {

    abstract fun ticketDbDao(): TicketDbDao

    companion object {
        @Volatile
        private var INSTANCE: MyDatabase? = null

        fun getDatabase(context: Context, scope: CoroutineScope): MyDatabase {
            val tempInstance = INSTANCE
            if (tempInstance != null) {
                return tempInstance
            }
            synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    MyDatabase::class.java,
                    "my_database"
                )
        .build()
                INSTANCE = instance
                return instance
            }
        }
    }
}

Класс данных

@Entity(tableName = "ticket_table")
data class TicketDb (@ColumnInfo(name = "ticketnumber")  var ticketnumber: String = "1234567") {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id") var id: Int = 0
}

Дао

@Dao
interface TicketDbDao {

    @Insert
    suspend fun insert(ticket: TicketDb)

    @Query("SELECT * FROM ticket_table ORDER BY id DESC")
    fun getAllTickets(): LiveData<List<TicketDb>>
}

Репозиторий

class TicketRepository (private val ticketDbDao: TicketDbDao) {

    val allTickets: LiveData<List<TicketDb>> = ticketDbDao.getAllTickets()

    @WorkerThread
    suspend fun insert(ticket: TicketDb) {
        ticketDbDao.insert(ticket)
    }

}

Viewmodel

var ticketRepository: TicketRepository

val allTickets: LiveData<List<TicketDb>>

init {
    val ticketDao = MeinLottoDatabase.getDatabase(application, viewModelScope).ticketDbDao()
    ticketRepository = TicketRepository(ticketDao)
    allTickets = ticketRepository.allTickets
}

fun saveTicket() = viewModelScope.launch(Dispatchers.IO) {
        ticketRepository.insert(ticket.value!!.toTicketDb())
}

Метод saveTicket работает.Я скачал базу данных и все сохраненные записи присутствуют.Но всякий раз, когда я вызываю ticketRepository.allTickets, я получаю пустой список обратно.

Я установил точку останова в автоматически сгенерированном классе TicketDbDao_Impl в методе вызова в объекте Callable, но точка останова никогда не достигается.

@Override
  public LiveData<List<TicketDb>> getAllTickets() {
    final String _sql = "SELECT * FROM ticket_table";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    return __db.getInvalidationTracker().createLiveData(new String[]{"ticket_table"}, false, new Callable<List<TicketDb>>() {
      @Override
      public List<TicketDb> call() throws Exception {
        final Cursor _cursor = DBUtil.query(__db, _statement, false);
        try {
          // BREAKPOINT here
          final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
          final int _cursorIndexOfName = CursorUtil.getColumnIndexOrThrow(_cursor, "name");

Ответы [ 2 ]

1 голос
/ 12 июля 2019

Я пробовал один и тот же код с небольшими изменениями, отлично работает со мной

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ticket1 = TicketDb("1")
        val ticket2 = TicketDb("12")
        val ticket3 = TicketDb("1123")
        val ticket4 = TicketDb("4214")

        MyDatabase.getDatabase(applicationContext).ticketDbDao()?.run {
            insert(ticket1)
            insert(ticket2)
            insert(ticket3)
            insert(ticket4)
        }

        val data = MyDatabase.getDatabase(applicationContext).ticketDbDao().getAllTickets()

        Log.i("Hardik", "Data :$data")

    }
}

MyDatabase

@Database(entities = [TicketDb::class], version = 1)
abstract class MyDatabase : RoomDatabase() {

    abstract fun ticketDbDao(): TicketDbDao

    companion object {
        @Volatile
        private var INSTANCE: MyDatabase? = null

        fun getDatabase(context: Context): MyDatabase {
            val tempInstance = INSTANCE
            if (tempInstance != null) {
                return tempInstance
            }
            synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    MyDatabase::class.java,
                    "my_database"
                ).allowMainThreadQueries().build()
                INSTANCE = instance
                return instance
            }
        }
    }
}

TicketDb

@Entity(tableName = "ticket_table")
data class TicketDb(@ColumnInfo(name = "ticketnumber") var ticketnumber: String = "1234567") {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    var id: Int = 0
}

TicketDbDao @Dao interface TicketDbDao {

@Insert
fun insert(ticket: TicketDb)

@Query("SELECT * FROM ticket_table ORDER BY id DESC")
fun getAllTickets(): List<TicketDb>

}

это дает мне вставленные данные в журнал, как показано ниже

2019-07-12 15:48:51.179 30262-30262/com.hardik.demos I/Hardik: Data :[TicketDb(ticketnumber=4214), TicketDb(ticketnumber=1123), TicketDb(ticketnumber=12), TicketDb(ticketnumber=1), TicketDb(ticketnumber=4214), TicketDb(ticketnumber=1123), TicketDb(ticketnumber=12), TicketDb(ticketnumber=1), TicketDb(ticketnumber=1), TicketDb(ticketnumber=1), TicketDb(ticketnumber=1)]
1 голос
/ 10 июля 2019

Я думаю, что у вас есть проблема при получении данных из комнаты.Следующий код не проверен, но чтобы помочь вам, я пытаюсь решить.Проверьте и ответьте в комментарии, если это работает или нет.

@Dao
interface TicketDbDao {

    @Insert
    suspend fun insert(ticket: TicketDb)

    @Query("SELECT * FROM ticket_table ORDER BY id DESC")
    fun getAllTickets(): LiveData<List<TicketDb>>
}

Я думаю, что запрос помещения возвращает данные списка, но вы пытаетесь получить объект aliveata.Поэтому перейдите к следующему коду для операции dao .

@Dao
interface TicketDbDao {

    @Insert
    suspend fun insert(ticket: TicketDb)

    @Query("SELECT * FROM ticket_table ORDER BY id DESC")
    fun getAllTickets(): List<TicketDb>
}

TicketRepository

class TicketRepository (private val ticketDbDao: TicketDbDao) {

    val allTickets: List<TicketDb> 
        get() = ticketDbDao.getAllTickets()

    @WorkerThread
    suspend fun insert(ticket: TicketDb) {
        ticketDbDao.insert(ticket)
    }
}

Теперь в вашей viewmodel

var ticketRepository: TicketRepository

private val _allTickets = MutableLiveData<List<TicketDb>>() // backing property should be used for updating values

val allTickets: LiveData<List<TicketDb>> = _allTickets // mutable live data should not be exposed

init {
    val ticketDao = MeinLottoDatabase.getDatabase(application, viewModelScope).ticketDbDao()
    ticketRepository = TicketRepository(ticketDao)

}

fun getTicketValues(){
    _allTickets.value = ticketRepository.allTickets
}

fun saveTicket() = viewModelScope.launch(Dispatchers.IO) {
        ticketRepository.insert(ticket.value!!.toTicketDb())
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...