1

The following code is based the project https://github.com/enpassio/Databinding

I hope to determine whether exist a record by id, so I write the following code.

I think my code is not good, is these a simple way to determine whether exist a record by id using Room?

Can I directly a SQl and return Booean with @Dao? If so, how can I do?

Code

@Dao
interface ToyDao {

    @get:Query("SELECT * FROM toys")
    val allToys: LiveData<List<ToyEntry>>

    @Query("SELECT * FROM toys WHERE toyId = :id")
    fun getChosenToy(id: Int): LiveData<ToyEntry>

    ...
}



class ToyRepository private constructor(private val mDatabase: ToyDatabase, private val mExecutors: AppExecutors) {

    val toyList: LiveData<List<ToyEntry>>
        get() = mDatabase.toyDao().allToys

    fun getChosenToy(toyId: Int): LiveData<ToyEntry> {
        return mDatabase.toyDao().getChosenToy(toyId)
    }

    
    
    fun isExistRecord(toyId: Int):Boolean{
        val my=getChosenToy(toyId)
        if (my.value==null) return false else return true
    }

    ...
}
HelloCW
  • 843
  • 22
  • 125
  • 310

2 Answers2

2

according to @Yarin's answer, codes below I test can simply work.

@Query("SELECT EXISTS (SELECT * FROM _table WHERE _id = :id)")
fun exists(id: Id): Boolean

But as I test, it seems not speed up with this method, maybe I'm not write in good way..

Environment

  • Emulator Pixel 2 API 28
  • 100000+ Rows
  • Query 10000 times in 1372ms
    @Query("SELECT EXISTS (SELECT * FROM _table WHERE _id = :id)")
    fun exists(id: Long): Boolean
    
  • Query 10000 times in 1364ms
    @Query("SELECT * FROM _table WHERE _id = :id")
    fun getItem(id: Long): Item
    

    UPDATE

    You can use LIMIT as TOP in SQLite, and usually here uses List for multiple results ( if LIMIT is not 1 ).

    @Query("SELECT * FROM _table WHERE _id = :id LIMIT 1")
    fun getItem(id: Long): List<Item>
    

    and it could be also Item because we know the result will be single.

    @Query("SELECT * FROM _table WHERE _id = :id LIMIT 1")
    fun getItem(id: Long): Item
    
  • Hababa
    • 551
    • 5
    • 8
    • Thanks! How can I write `@Dao interface ToyDao{... }` for `SELECT TOP 1 toys.id FROM toys WHERE toys.id = :id` ? – HelloCW Jun 29 '20 at 12:08
    • It seems using `LIMIT` in `SQLite`, so it would be `SELECT * FROM _table WHERE _id = :id LIMIT 1` – Hababa Jun 29 '20 at 23:46
    • Thanks! Could you give me the code ? I don't know what `SELECT * FROM _table WHERE _id = :id LIMIT 1 ` will return. – HelloCW Jun 30 '20 at 02:44
    1

    you can check out this thread fastest-way-to-determine-if-record-exists

    basically you have 2 options:

    1. use the TOP 1 and it will look like - SELECT TOP 1 toys.id FROM toys WHERE toys.id = :id
    2. use EXISTS or NO EXISTS and it will look like -
    IF EXISTS (SELECT * FROM toys WHERE id = :id)
    BEGIN
    --do what you need if exists
    END
    ELSE
    BEGIN
    --do what needs to be done if not
    END
    
    Yarin Shitrit
    • 297
    • 4
    • 16
    • Thanks! How can express your ideas in `@Dao interface ToyDao{... }`' ? – HelloCW Jun 29 '20 at 07:01
    • simply write : `@Query("SELECT EXISTS (SELECT * FROM toys WHERE toyId = :id)") fun selectToyIfExists(id: Int): LiveData` – Yarin Shitrit Jun 29 '20 at 12:13
    • Thanks! are you sure that `@Query("SELECT EXISTS (SELECT * FROM toys WHERE toyId = :id)") fun selectToyIfExists(id: Int)` will return `LiveData` ? – HelloCW Jun 29 '20 at 12:18
    • you are right it wont, it will return a boolean (true) if it does exist. if you want to retrieve the actual `LiveData` then use it and if it returns true then just simply use the query `"(SELECT * FROM toys WHERE toyId = :id)"` since you already know the toy exists – Yarin Shitrit Jun 29 '20 at 13:24