Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly get table name in DAO class using Android Room

I wonder how to avoid hard coding when using table name in Android Room query. I develop in Kotlin, but to be honest in this problem it doesn't matter is Java or Kotlin.

Let's see that simple classes:

DAO interface:

@Dao
interface UserDAO {

    @Query("SELECT * FROM USER")
    fun getAll(): List<User>
}

Entity class:

@Entity(tableName = "USER")
class User {
}

You can see that the table name "USER" is hard coded in @Query in UserDAO. How to avoid that? How to refer to @Entity parameter tableName?

I would like to have all names in one and only one place.

like image 758
wapn Avatar asked Mar 05 '18 11:03

wapn


2 Answers

You can make a constant in any of Util classes and can refer that variable in Entity and Dao class like this:-

Suppose in MainActivity you have

    companion object {
        const val TABLE_NAME: String="Cheese"
    }

Entity class

@Entity(tableName = MainActivity.TABLE_NAME)

and Dao class will be

@Query("SELECT * FROM "+MainActivity.TABLE_NAME)

Note :- This is an usual approach to avoid hard coded naming may be you can get table name from Entity class(Needs to be explored) :) .

like image 145
Suraj Nair Avatar answered Nov 14 '22 21:11

Suraj Nair


Currently for both, Kotlin and Java you can rely on the-built in SQL syntax higlighting. As a result, when you type the content of a your query, Android Studio suggests already defined table names. Maybe you have turned that feature off somehow? Don't forget to inject Android Room SQL Language

All in all, if you prefer to keep hardcoded things away, why not define a companion object belonging to the Entity class? Imho, mixing Data (layer) and Activity class is not a nice concept. Data does't know about something like activity (or any UI related stuff). Having Utils sounds like having a bug for everything, not separated from concerns point of view.

Maybe the following code would meet you requirement:

@Entity(tableName = WordPl.TABLE_NAME)
data class WordPl(var id: Int,                      
                  var word: String) {

    companion object {
        const val TABLE_NAME = "word_pl"
    }

}

Then in your DAO, you can use Kotlin String Template:

@Dao
interface DictionaryDao {

    @Query("Select * from ${WordPl.TABLE_NAME}")
    fun getAllWords(): List<WordPl>

}
like image 21
gary0707 Avatar answered Nov 14 '22 21:11

gary0707