web-dev-qa-db-ja.com

ルームデータベース内のブールクエリのハードコード

ユーザーの潜在的な一致のリストを表示するAndroidアプリケーションを作成しています。ユーザーはユーザーをクリックして、そのユーザーを「いいね」することができます。それらのすべてをローカルに保存します。

次のような一致のリストを取得するクエリを作成できます。

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

これがうまくいくことを学びました。ただし、likedをfalseに設定するシナリオは予見できません。したがって、ブール条件をハードコーディングする方法があるかどうかは知りませんか。私が試した場合:

@Query("SELECT * FROM match WHERE liked = true ORDER BY match DESC LIMIT :limit")

コンパイル時に次のエラーが表示されます。

Error:(8, 0) Gradle: error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: true)

クエリ文字列にこのブール値をハードコーディングするにはどうすればよいですか?

私も試しました:

  • 条件を一重引用符で囲む
    • @Query("SELECT * FROM match WHERE liked = 'true' ORDER BY match DESC LIMIT :limit")
41
AdamMc331

SQLiteにはブールデータ型がありません。ルームはINTEGER列にマップし、true1に、false0にマッピングします。

だから、私はこれがうまくいくと期待しています:

@Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")

この動作は文書化されていないことに注意してください。ただし、変更を処理するために移行を使用する必要があるため、変更しないでください(少なくとも警告音が鳴らない限り)。

127
CommonsWare

CommonWareのアプローチは機能し、OPの質問にも直接回答します。ただし、データベースについてこのような仮定を立てるのは好きではありません。仮定は安全でなければなりませんが、ブールの実装を変更することをRoomが決定した場合、今後予期しない作業が発生する可能性があります。

より良いアプローチは、ブール値1または0をクエリにハードコーディングしないことです。データベースがリポジトリの背後にある場合でも、リポジトリが適切なAPIを公開する可能性があります。個人的には、とにかくデータベースの実装から大きなコードベースを保護することは良いことだと思います。

Dao Method(OPの質問からコピー)

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

倉庫

class Repository {
    public Flowable<List<Match>> getLikedMatches() {
        return dao.getMatches(6, true);
    }
}

もちろん、これは特定のアーキテクチャスタイルを想定しているという点で、意見に基づいたオプションです。ただし、内部データベースについては想定していません。リポジトリがデータベースを保護していなくても、どこにでもtrueを渡すことにより、データベースへの呼び出しを行うことができます-また、基礎となるデータに関する仮定を行う必要もありません。

13
methodsignature