我有一个方法:
public int getCountOfFavoriteMovies(){
Cursor cursor = mDatabase.query(
MovieDbScheme.NAME,
null,
MovieDbScheme.IS_FAVORITE + " = 1",
null,
null,
null,
null
);
try{
return cursor.getCount();
}
finally {
cursor.close();
}
}
它返回 7,但如果我用以下代码替换它:
Cursor cursor = mDatabase.query(
MovieDbScheme.NAME,
null,
MovieDbScheme.IS_FAVORITE + " = ?",
new String[]{Integer.toString(1)},
null,
null,
null
);
它出于某种原因返回 0。 为什么?他们不一样吗?
SQLite 中的数据类型 是一个复杂的概念,您必须仔细研究它以避免出现此类问题。
您定义了没有任何数据类型的列
MovieDbScheme.IS_FAVORITE
,这意味着它没有type affinity。当您在
?
方法的 selection
参数中使用
query()
占位符时,这些占位符将被 selectionArgs
的值替换为字符串(因此,如果您传递 1
它将被替换为'1'
).这意味着发生的比较将在一个没有亲和力的列和一个字符串之间进行。
在这种情况下,SQLite 不执行关联转换,
1 = '1'
将返回 false
,因为:
对于 SQLite INTEGER 值总是小于 TEXT 值
(来自比较示例)
你应该做的是将列
MovieDbScheme.IS_FAVORITE
定义为 INTEGER
(如果你的 SQLite 版本是 3.23.0+,则为 BOOLEAN
),在这种情况下,SQLite 将执行关联转换并比较表达式的两个操作数 1 = '1'
作为整数。查看演示。
因此,从您尝试应用的设备上卸载该应用,将您的代码更改为:
MovieDbScheme.IS_FAVORITE + " INTEGER"
在
CREATE TABLE
语句中并重新运行。那是因为你将它作为字符串而不是整数进行比较,所以你的查询将导致 WHERE 条件,如
IS_FAVORITE = '1'
而不是 IS_FAVORITE = 1
我认为你可以直接在选择参数中嵌入整数,因为它们不会受到注入的伤害。