web-dev-qa-db-ja.com

クエリによる部屋のユーザー設定可能な順序

通常のRoomからSqliteを使用するようにアプリを移行していますが、問題が発生しているのは、ユーザーが構成できるorderbyステートメントを持つクエリがいくつかあることです。リストの順序を表示する方法を変更します。

Roomでは動的なorderbyステートメントが許可されていないため、orderbyステートメントごとに個別のクエリを実行する必要があるようです。

誰かがこの問題を回避するより良い方法を見つけたので、1つのクエリステートメントを使用できます。変更されるのはorder by句だけですが、私の場合は、基本的に同じ15個の追加のクエリステートメントを記述する必要がありますか?

11
tyczj

Room 1.1には、この問題を解決するために使用できるRawQueryがあります。

 @Dao
 interface RawDao {
     @RawQuery
     User getUserViaQuery(SupportSQLiteQuery query);
 }
 SimpleSQLiteQuery query = new SimpleSQLiteQuery("SELECT * FROM User WHERE id = ? LIMIT 1",
         new Object[]{userId});
 User user2 = rawDao.getUserViaQuery(query);

https://developer.Android.com/reference/Android/Arch/persistence/room/RawQuery

5
tyczj

私は今同じ問題に直面しています。実行できることは、CASEを使用することです。

SELECT * FROM Table
ORDER BY 
CASE WHEN :parameter = 1 THEN Column END ASC,
CASE WHEN :parameter = 2 THEN Column2 END DESC

ただし、ViewModelも使用していると想定しているため、毎回再初期化する必要があります。この方法は、15個のクエリを作成するよりも少し優れていると思いますが、それほどコンパクトではないかもしれません。

この answer にも良い例がありますが、論理が逆になっていると思います。

7
Suleyman

tyczj がすでに提案しているように、RawQueryを使用できます。さらに、SimpleSQLiteQueryをDAOに移動することもできるため、DAOの外部にSQLステートメントはありません。

DAOは、抽象クラスを介して定義することもできます。これにより、SimpleSQLiteQueryを実行するメソッドを追加できます。

例:

@DAO
public abstract class UserDao {

    @RawQuery
    public abstract List<User> getUsersViaRawQuery(SupportSQLiteQuery query);

    public List<User> getUsersOrderBy(String column) {
        String statement = "SELECT * FROM user ORDER BY " + column + " ASC";
        SupportSQLiteQuery query = new SimpleSQLiteQuery(statement, new Object[]{});
        return getUsersViaRawQuery(query);
    }

}

列パラメーターは、特定の値のみを許可する列挙型に置き換えることもできます。

例:

private static String createOrderByString(Order order) {
    switch (order) {
        case NAME:
            return "ORDER BY first_name ASC, last_name ASC";
        case AGE:
            return "ORDER BY age DESC";
        default:
            return "";
    }
}
2
Matt Ke

OurDaoのメソッドではパラメーターを使用できません。

@Query("SELECT * FROM sometable order by :orderClause DESC")
    List<Islem> findOneUserName(String orderClause);//didn't work

このクエリパラメータは、SQLインジェクションを回避するためのwhereパラメータでのみ使用されます。

0
anilkay