I am migrating an app to use Room
from normal Sqlite
and one part that I am having trouble with is that there are several queries that have an orde
As tyczj already suggested you can us a RawQuery
. In addition, the SimpleSQLiteQuery
can also be moved into the DAO so there are no SQL statements outside of the DAO.
A DAO can also be defined via an abstract class. This allows you to add a method which executes the SimpleSQLiteQuery
.
Example:
@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);
}
}
The column parameter could also be replaced by an enum, which only allows specific values.
Example:
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 "";
}
}
I'm facing the same problem right now. The thing that can be done is to use CASE:
SELECT * FROM Table
ORDER BY
CASE WHEN :parameter = 1 THEN Column END ASC,
CASE WHEN :parameter = 2 THEN Column2 END DESC
But I'm assuming you are using a ViewModel
as well, so you will probably have to reinitialise it every time. I think this way is a little bit better than writing 15 queries, maybe not as compact though.
This answer also has a nice example, but the logic is reversed I believe.
You can't use parameters in Our Dao's method.
@Query("SELECT * FROM sometable order by :orderClause DESC")
List<Islem> findOneUserName(String orderClause);//didn't work
This Query parameters only use in where parameters for avoid Sql injections.
In Room 1.1 there is now a RawQuery
that can be used that solves this issue
@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