我相信以下查询会做你想做的事(至少在原则上):-
@Query("SELECT * FROM `table` WHERE color = (CASE WHEN length(:color) THEN :color ELSE color END) AND category = (CASE WHEN length(:category) THEN :category ELSE category END)")
List<Items> filteredItems(String color, String category);
以下是基于您的代码的工作示例,用于演示上述内容。
假设颜色和类别是字符串。如果 id 是,那么 CASE .... WHEN .... THEN .... END 会有点不同,但基本原理是一样的。也就是说,如果提供了合适的值,则使用传递的值,否则使用正在处理的列的值。
- 如果颜色和类别是 id(长整数),那么您可以使用
-
@Query("SELECT * FROM table WHERE color = (CASE WHEN :color > 0 THEN :color ELSE color END) AND category = (CASE WHEN :category > 0 THEN :category ELSE category END)") List<Items> filteredItems(String color, String category);
-
这假设 id 总是大于 0。
-
此 sn-p 尚未测试/运行,因此可能包含一些错误。
首先是实体表:-
@Entity
class Table {
@PrimaryKey
Long id = null;
String color = null;
String category = null;
public Table(){}
@Ignore
public Table(String color, String category) {
this.color = color;
this.category = category;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
RawDao 界面:-
@Dao
interface RawDao {
@Insert
long insert(Table table);
@Query("SELECT * FROM `table` WHERE color = (CASE WHEN length(:color) THEN :color ELSE color END) AND category = (CASE WHEN length(:category) THEN :category ELSE category END)")
List<Table> filteredItems(String color, String category);
}
- 为了方便/简洁,使用了列表(根据您查询名为 table 的表的查询,也许它应该是更好的 item)
@Database 类 TheDatabase :-
@Database(entities = {Table.class},version = 1)
abstract class TheDatabase extends RoomDatabase {
abstract RawDao getDao();
private static volatile TheDatabase instance = null;
public static TheDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase.class,"mydb")
.allowMainThreadQueries().build();
}
return instance;
}
}
最后是一个插入一些行然后提取数据的活动,使用以下排列将其写入日志:-
- 既不是颜色也不是类别(全选)。即传递了空字符串。
- 仅传递的颜色值
- 颜色和类别值传递
- 仅通过了类别值。
:-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
RawDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getDao();
dao.insert(new Table("black","cat1"));
dao.insert(new Table("green","cat1"));
dao.insert(new Table("black","cat2"));
dao.insert(new Table("green","cat2"));
logTableInfo(dao.filteredItems("",""),"RUN1"); /* get everything as no values for either argument */
logTableInfo(dao.filteredItems("black",""),"RUN2"); /*get color black irrespective of category */
logTableInfo(dao.filteredItems("black","cat1"),"RUN3"); /* get color black in category cat1 */
logTableInfo(dao.filteredItems("","cat1"),"RUN4"); /* get all that have cat1 as the category irresepctive of color */
}
private void logTableInfo(List<Table> items, String extra) {
for(Table t: items) {
Log.d("TABLEINFO" + extra,"Color is " + t.color + " Category is " + t.category + " ID is " + t.id);
}
}
}
结果
2021-07-05 21:53:52.616 D/TABLEINFORUN1: Color is black Category is cat1 ID is 1
2021-07-05 21:53:52.617 D/TABLEINFORUN1: Color is green Category is cat1 ID is 2
2021-07-05 21:53:52.617 D/TABLEINFORUN1: Color is black Category is cat2 ID is 3
2021-07-05 21:53:52.617 D/TABLEINFORUN1: Color is green Category is cat2 ID is 4
2021-07-05 21:53:52.619 D/TABLEINFORUN2: Color is black Category is cat1 ID is 1
2021-07-05 21:53:52.619 D/TABLEINFORUN2: Color is black Category is cat2 ID is 3
2021-07-05 21:53:52.619 D/TABLEINFORUN3: Color is black Category is cat1 ID is 1
2021-07-05 21:53:52.620 D/TABLEINFORUN4: Color is black Category is cat1 ID is 1
2021-07-05 21:53:52.620 D/TABLEINFORUN4: Color is green Category is cat1 ID is 2
附加
这是一个构建相对灵活版本的示例,其中构建了 SQL 并根据评论。
通过灵活,它不特定于表/实体,它可以满足任意数量的列/值对(但只有字符串值,必须转换 BLOB (byte[]))。使用ContentValues 可以克服 BLOB 限制)。 但是,与任何使用 @RawQuery 一样,您会丢失编译时检查,因此问题将导致运行时错误。
- 请注意,这并不全面,而是一个可以满足某些情况的示例:-
先道:-
@RawQuery
List<Table> filteredItemsAlt(SupportSQLiteQuery query);
然后为方便起见,Table实体中的一个方法:-
public static SimpleSQLiteQuery buildQuery(String fromClause, String[] whereColumns, String[] whereValues) {
// Run query that returns nothing if columns and args (values) mismatch
SimpleSQLiteQuery rv = new SimpleSQLiteQuery(fromClause + " WHERE 1 = 2", null);
if (whereColumns.length != whereValues.length) return rv;
// OK to go so prepare build variables
ArrayList<String> bindArgs = new ArrayList<>();
StringBuilder whereclause = new StringBuilder();
// For each column and therefore arg/value
for(int i=0; i < whereColumns.length; i++) {
if (whereclause.length() > 1) whereclause.append(" AND "); // if where clause is not empty then add AND
whereclause.append(whereColumns[i]).append(" = "); // column name = part
// if value/arg is null or string is empty then affectively ignore (could alternatively ignore the AND and column = column)
if (whereValues[i] == null || whereValues[i].length() < 1) whereclause.append(whereColumns[i]);
// otherwise prepare to bind the value i.e ? in the SQL and value stored for bind
else {
whereclause.append(" ? ");
bindArgs.add(whereValues[i]);
}
}
Log.d("WHERE_CLAUSE","WHERE clause is " + whereclause.toString());
// check to se if there is a where clause, if so build the full SQL
if (whereclause.length() > 0 ) {
rv = new SimpleSQLiteQuery(fromClause + " WHERE " + whereclause.toString(), bindArgs.toArray());
} else {
// otherwise build sql without WHERE clause
rv = new SimpleSQLiteQuery(fromClause);
}
return rv;
}
-
fromClause 是包含 fromClause 的 SELECT SQL
-
whereColumns 是要比较的列列表
-
whereValues 是值列表(null 或空字符串获取列的所有行)
在一个活动中(复制第一个结果)你可以:-
logTableInfo(dao.filteredItemsAlt(Table.buildQuery(
"SELECT * FROM `table`",
new String[]{"color","category"},
new String[]{null,null}
)),"ARUN1");
logTableInfo(dao.filteredItemsAlt(Table.buildQuery(
"SELECT * FROM `table`",
new String[]{"color","category"},
new String[]{"black",null}
)),"ARUN2");
logTableInfo(dao.filteredItemsAlt(Table.buildQuery(
"SELECT * FROM `table`",
new String[]{"color","category"},
new String[]{"black","cat1"}
)),"ARUN3");
logTableInfo(dao.filteredItemsAlt(Table.buildQuery(
"SELECT * FROM `table`",
new String[]{"color","category"},
new String[]{null,"cat1"}
)),"ARUN4");
结果:-
2021-07-06 17:07:14.840 D/WHERE_CLAUSE: WHERE clause is color = color AND category = category
2021-07-06 17:07:14.841 D/TABLEINFOARUN1: Color is black Category is cat1 ID is 1
2021-07-06 17:07:14.841 D/TABLEINFOARUN1: Color is green Category is cat1 ID is 2
2021-07-06 17:07:14.841 D/TABLEINFOARUN1: Color is black Category is cat2 ID is 3
2021-07-06 17:07:14.841 D/TABLEINFOARUN1: Color is green Category is cat2 ID is 4
2021-07-06 17:07:14.841 D/WHERE_CLAUSE: WHERE clause is color = ? AND category = category
2021-07-06 17:07:14.843 D/TABLEINFOARUN2: Color is black Category is cat1 ID is 1
2021-07-06 17:07:14.843 D/TABLEINFOARUN2: Color is black Category is cat2 ID is 3
2021-07-06 17:07:14.843 D/WHERE_CLAUSE: WHERE clause is color = ? AND category = ?
2021-07-06 17:07:14.846 D/TABLEINFOARUN3: Color is black Category is cat1 ID is 1
2021-07-06 17:07:14.847 D/WHERE_CLAUSE: WHERE clause is color = color AND category = ?
2021-07-06 17:07:14.849 D/TABLEINFOARUN4: Color is black Category is cat1 ID is 1
2021-07-06 17:07:14.849 D/TABLEINFOARUN4: Color is green Category is cat1 ID is 2
- 请注意,以上内容的组合比较仓促,因此可能需要进行一些调整,因此更多的是原则上的示例。 例如如果你想订购它怎么办? (修辞)