2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VolareAdvent Calendar 2021

Day 21

[Android] Roomの@RawQueryの使いどころ

Last updated at Posted at 2021-12-20

利用すべきでないケース

使いどころの前に、まず使うべきではないケースについて説明します。RawQueryのドキュメントには以下のサンプルコードが記載されていますが、どれも基本的には利用すべきではないです。

  • Observable Queries
  • Returning POJOs
  • POJOs with Embedded Fields
  • Relations

適切にプレースホルダを利用すれば、これらのほとんどのクエリを他の@Query等のアノテーションでも実現できます。@RawQueryを利用してしまうとコンパイル時のバリデーションが出来ないため、Roomのメリットを捨てることになります。

使いどころ

Roomの他の機能を利用して、どうしても実現できない場合には@RawQueryの出番です。

PRAGMA

PRAGMAの利用が@RawQueryを利用したいケースの中でかなり多いのではないかと思います。例えばPRAGMA compile_optionsというクエリで、SQLiteのコンパイルオプションの一覧を取得することが出来ます。

例として、SQLiteの全文検索(FTS)のクエリの構文を決定するコンパイルオプション(SQLITE_ENABLE_FTS3_PARENTHESIS)の取得をしてみます。

@Dao
abstract class MyDao {
    val isEnhancedQueryEnabled: Boolean by lazy {
        // PRAGMAでコンパイルオプションを取得すると"SQLITE_"のプレフィックスが省略されます。
        "ENABLE_FTS3_PARENTHESIS" in selectCompileOptions()
    }

    @RawQuery
    protected abstract fun selectCompileOptions(
        query: SelectCompileOptionsQuery = SelectCompileOptionsQuery
    ): List<String>

    protected object SelectCompileOptionsQuery : SupportSQLiteQuery {
        override fun getSql(): String = "PRAGMA compile_options"

        override fun bindTo(statement: SupportSQLiteProgram?) = Unit

        override fun getArgCount(): Int = 0
    }
}

SQLITE_ENABLE_FTS3_PARENTHESISがコンパイルオプションとして指定されている場合に、isEnhancedQueryEnabledtrueになります。

実装時のコツですが、@RawQueryは出来ることが多いので、できるだけ使用を制限することをおすすめします。SupportSQLiteQueryを継承した特定のクエリ専用のクラスを作り、@RawQueryを付けた関数のデフォルト引数で渡すと良いでしょう。

サンプルコードはこちらにあります。

テーブルを動的に指定

テーブルを動的に指定するような特殊なクエリは、DAOの関数の引数をバインドすることが出来ません。@RawQueryを使って実装できますが、このケースではRoom自体を使わないほうが良いかもしれません。

Roomが生成するコードに問題がある

Roomが生成するコードにバグが存在したり、パフォーマンスが悪い場合に@RawQueryが役立つかもしれません。

SQLiteを暗号化するライブラリのSQLCipherとRoomを組み合わせた際に、特定のクエリでアプリがクラッシュする問題が以前あったのですが、それが解決するまでの間は@RawQueryで実装したクエリで代用したことがあります。

おわりに

実用的な@RawQueryの使いどころとしてはPRAGMAぐらいしか無い気がします。もし効果的に@RawQueryを利用している方がいましたら、コメントでどう使っているかを教えてくれると嬉しいです。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?