LoginSignup
1
3

More than 3 years have passed since last update.

Roomで動的に生成したクエリ(SQL文)を扱う方法

Posted at

はじめに

Roomを用いてDBを扱う際に、動的に生成したクエリを扱う必要があったため、その時に調べたことについてまとめてみました。

方法としては以下の2つ

  • @RawQueryアノテーションを使用
  • RoomDatabase#queryメソッドを使用

今回使用するデータベース

以下のようなメモを保存するテーブルを持つDBを例に説明していきます。

@Entity
data class Memo(
    @PrimaryKey(autoGenerate = true)
    var id: Int,
    val memo: String
)

また、事前に以下のデータを持っているものとします。

id memo
1 メモ1
2 メモ2
3 メモ3

@RawQueryアノテーションを使用する場合

まず、DAOインタフェース内に関数を定義しておきます。

@Dao
interface MemoDAO {
    @RawQuery
    fun getMemoViaQuery(query: SupportSQLiteQuery): String
}

次にDBにアクセスしたい箇所においてSimpleSQLiteQuery()を用いてクエリを生成し、DAOインタフェース内に定義した関数の引数に渡してやれば実行できます。

val query = SimpleSQLiteQuery("select memo from Memo WHERE id = 2")

launch(Dispatchers.IO){
    val list = dao.getMemoViaQuery(query)
    Log.i("tag", memo)
}

ログ:該当のメモが取り出せてることが確認できました。

I/tag: メモ2

コード全体としては以下のような感じです。簡略化ためActivity内で実装してます。

class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {

    private lateinit var db: MemoDatabase
    private lateinit var dao: MemoDAO

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

        this.db = Room.databaseBuilder(
            applicationContext,
            MemoDatabase::class.java,
            "memo.db"
        ).build()
        this.dao = db.memoDAO()

        val query = SimpleSQLiteQuery("select memo from Memo WHERE id = 2")

        launch(Dispatchers.IO){
            val memo = dao.getMemoViaQuery(query)
            Log.i("tag", memo)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        cancel() // cancel is extension on CoroutineScope
    }
}

RoomDatabase#queryメソッドを使用する場合

RoomDatabase#queryの返り値がCursorオブジェクトであることに気をつけて値を取り出します。

val query = SimpleSQLiteQuery("select memo from Memo WHERE id = 3")

launch(Dispatchers.IO){
    val cursor =  db.query(query)
    cursor.moveToNext()
    val idxMemo = cursor.getColumnIndex("memo")
    val memo = cursor.getString(idxMemo)
    Log.i("tag", memo)
}  

ログ:該当のメモが取り出せてることが確認できました。

I/tag: メモ3

コード全体

class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {

    private lateinit var db: MemoDatabase
    private lateinit var dao: MemoDAO

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

        this.db = Room.databaseBuilder(
            applicationContext,
            MemoDatabase::class.java,
            "memo.db"
        ).build()
        this.dao = db.memoDAO()

        val query = SimpleSQLiteQuery("select memo from Memo WHERE id = 3")

        launch(Dispatchers.IO){
            val cursor =  db.query(query)
            cursor.moveToNext()
            val idxMemo = cursor.getColumnIndex("memo")
            val memo = cursor.getString(idxMemo)
            Log.i("tag", memo)
        }  
    }

    override fun onDestroy() {
        super.onDestroy()
        cancel() // cancel is extension on CoroutineScope
    }
}

Roomで動的に生成したクエリを扱うことについて説明しました。
以上です。

参考にしたサイト

RawQuery - Android Developers
RoomDatabase - Android Developers

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3