SQLiteDatabase.query 方法
Posted
技术标签:
【中文标题】SQLiteDatabase.query 方法【英文标题】:SQLiteDatabase.query method 【发布时间】:2012-05-22 23:03:45 【问题描述】:我使用的是SQLiteDatabase的查询方法。如何使用查询方法?
我试过了:
Cursor cursor = sqLiteDatabase.query(
tableName, tableColumns, whereClause, whereArgs, groupBy, having, orderBy);
tableColumns - 列参数构造如下。
String[] columns = new String[]KEY_ID, KEY_CONTENT;
如果我们需要获取所有的字段,列参数应该如何构造。我们需要在字符串数组中包含所有字段名称吗?
如何正确使用查询方式?
【问题讨论】:
试试this这样的简单方法 我知道那种方法。但我正在尝试学习如何实现查询方法而不是 rawQuery。 【参考方案1】:表格列
null
用于所有列,如 SELECT * FROM ...
new String[] "column1", "column2", ...
用于 SELECT column1, column2 FROM ...
中的特定列 - 您也可以在此处放置复杂的表达式:new String[] "(SELECT max(column1) FROM table1) AS max"
将为您提供一个名为 max
的列,其中包含 column1
的最大值
where子句
你放在WHERE
之后没有那个关键字的部分,例如"column1 > 5"
应该包含?
用于动态的事物,例如"column1=?"
-> 见whereArgs
whereArgs
指定在whereClause
中按出现顺序填充每个?
的内容
其他人
就像whereClause
关键字后面的语句或null
,如果你不使用它。
示例
String[] tableColumns = new String[]
"column1",
"(SELECT max(column1) FROM table2) AS max"
;
String whereClause = "column1 = ? OR column1 = ?";
String[] whereArgs = new String[]
"value1",
"value2"
;
String orderBy = "column1";
Cursor c = sqLiteDatabase.query("table1", tableColumns, whereClause, whereArgs,
null, null, orderBy);
// since we have a named column we can do
int idx = c.getColumnIndex("max");
相当于下面的原始查询
String queryString =
"SELECT column1, (SELECT max(column1) FROM table1) AS max FROM table1 " +
"WHERE column1 = ? OR column1 = ? ORDER BY column1";
sqLiteDatabase.rawQuery(queryString, whereArgs);
通过使用 Where/Bind -Args 版本,您可以自动获得转义值,并且您不必担心输入数据是否包含 '
。
不安全:String whereClause = "column1='" + value + "'";
保险箱:String whereClause = "column1=?";
因为如果 value 包含 '
您的语句要么中断并且您得到异常或执行意外的事情,例如 value = "XYZ'; DROP TABLE table1;--"
甚至可能删除您的表,因为该语句将变成两个语句和一个注释:
SELECT * FROM table1 where column1='XYZ'; DROP TABLE table1;--'
使用 args 版本 XYZ'; DROP TABLE table1;--
将被转义为 'XYZ''; DROP TABLE table1;--'
并且只会被视为一个值。即使'
不是为了做坏事,人们在他们的名字中使用它或在文本、文件名、密码等中使用它仍然很常见。所以请始终使用 args 版本。 (虽然可以将int
和其他原语直接构建到whereClause
中)
【讨论】:
Limit/offset 在这个... group by 中属于哪里?有? orderby? @Lion789 有几个版本具有limit
参数,例如developer.android.com/reference/android/database/sqlite/… 最后只是简单的文本连接,因此您可以输入例如"some_column LIMIT 10"
到 orderBy
仍然可以工作
这里可以选择加入 2 个表吗?
@VijayKumbhoje 你应该可以放例如table1 CROSS JOIN table2
作为表名。但有一点我会看 rawquery:***.com/q/10598137/995891
@VijayKumbhoje 无论你觉得更舒服/最终看起来更干净。 query
方法只是在参数(see source) 中添加一些关键字,如@987654358@ 和FROM
,然后使用生成的查询字符串执行rawQuery
。如果您的查询不适合query
的可用参数,请自己编写查询字符串。【参考方案2】:
这是一个更笼统的答案,旨在为未来的观众提供快速参考。
示例
SQLiteDatabase db = helper.getReadableDatabase();
String table = "table2";
String[] columns = "column1", "column3";
String selection = "column3 =?";
String[] selectionArgs = "apple";
String groupBy = null;
String having = null;
String orderBy = "column3 DESC";
String limit = "10";
Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
来自documentation的解释
table
String: 编译查询的表名。columns
String:要返回的列的列表。传递 null 将返回所有列,不鼓励这样做以防止读取数据 来自不会被使用的存储空间。selection
String:一个过滤器,声明要返回哪些行,格式化为 SQL WHERE 子句(不包括 WHERE 本身)。通过 null 将返回给定表的所有行。selectionArgs
String:您可以在选择中包含 ?s,它将被 selectionArgs 中的值替换,以便它们 出现在选择中。这些值将绑定为字符串。groupBy
字符串:声明如何对行进行分组的过滤器,格式化为 SQL GROUP BY 子句(不包括 GROUP BY 本身)。传递空值 将导致行不被分组。having
字符串:一个过滤器声明哪些行组包含在游标中,如果正在使用行分组,格式化为 SQL HAVING 子句(不包括 HAVING 本身)。传递 null 将导致所有行 要包括的组,并且在不进行行分组时是必需的 用过。orderBy
String:如何对行进行排序,格式化为 SQL ORDER BY 子句(不包括 ORDER BY 本身)。传递 null 将使用 默认排序顺序,可能是无序的。limit
String:限制查询返回的行数,格式为 LIMIT 子句。传递 null 表示没有 LIMIT 子句。
【讨论】:
【参考方案3】:Where 子句和 args 共同构成 SQL 查询的 WHERE 语句。所以说你想表达
WHERE Column1 = 'value1' AND Column2 = 'value2'
那么你的 whereClause 和 whereArgs 将如下所示
String whereClause = "Column1 =? AND Column2 =?";
String[] whereArgs = new String[]"value1", "value2";
如果您想选择所有表格列,我相信传递给 tableColumns 的空字符串就足够了。
【讨论】:
不要将?
包含在'
中,如果需要,'
会自动添加【参考方案4】:
如果你的 SQL 查询是这样的
SELECT col-1, col-2 FROM tableName WHERE col-1=apple,col-2=mango
GROUPBY col-3 HAVING Count(col-4) > 5 ORDERBY col-2 DESC LIMIT 15;
那么对于 query() 方法,我们可以这样做:-
String table = "tableName";
String[] columns = "col-1", "col-2";
String selection = "col-1 =? AND col-2=?";
String[] selectionArgs = "apple","mango";
String groupBy =col-3;
String having =" COUNT(col-4) > 5";
String orderBy = "col-2 DESC";
String limit = "15";
query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
【讨论】:
【参考方案5】:db.query(
TABLE_NAME,
new String[] TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO ,
TABLE_ROW_ID + "=" + rowID,
null, null, null, null, null
);
TABLE_ROW_ID + "=" + rowID
,这里的=
是where
子句。要选择所有值,您必须提供所有列名:
or you can use a raw query like this
db.rawQuery("SELECT * FROM permissions_table WHERE name = 'Comics' ", null);
这是一个good tutorial 用于数据库。
【讨论】:
以上是关于SQLiteDatabase.query 方法的主要内容,如果未能解决你的问题,请参考以下文章
在 SQLiteDatabase.query() 中使用 String[] selectionArgs