SQLiteDatabase db = mOpenHelper.getReadableDatabase(),得到一个可读的SQLiteDatabase 实例。
Cursor c = qb.query(db, projection, selection, selectionArgs, null,null, orderBy)语句,这个查询类似于一个标准的SQL查询,但是这个查询是SQLiteQueryBuilder 来发起的,而不是SQLiteDatabase 直接发起的,所以在参数方面略有不同。这个函数为 query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)下边将各个参数介绍一下。
第一个参数为要查询的数据库实例。
第二个参数是一个字符串数组,里边的每一项代表了需要返回的列名。
第三个参数相当于SQL语句中的where部分。
第四个参数是一个字符串数组,里边的每一项依次替代在第三个参数中出现的问号(?)。
第五个参数相当于SQL语句当中的groupby部分。
第六个参数相当于SQL语句当中的having部分。
第七个参数描述是怎么进行排序。
第八个参数相当于SQL当中的limit部分,控制返回的数据的个数。
SQLiteQueryBuilder
包:android.database.sqlite.SQLiteQueryBuilder
作用:SQL 查询辅助类,在写contentprovider时很适合
例: CallLogProvider实现的query:
1. private static final HashMap<String, String> sCallsProjectionMap;
2. static {
3.
4. // Calls projection map
5. sCallsProjectionMap = new HashMap<String, String>();
6. sCallsProjectionMap.put(Calls._ID, Calls._ID);
7. sCallsProjectionMap.put(Calls.NUMBER, Calls.NUMBER);
8. sCallsProjectionMap.put(Calls.DATE, Calls.DATE);
9. sCallsProjectionMap.put(Calls.DURATION, Calls.DURATION);
10. sCallsProjectionMap.put(Calls.TYPE, Calls.TYPE);
11. sCallsProjectionMap.put(Calls.NEW, Calls.NEW);
12. sCallsProjectionMap.put(Calls.CACHED_NAME, Calls.CACHED_NAME);
13. sCallsProjectionMap.put(Calls.CACHED_NUMBER_TYPE, Calls.CACHED_NUMBER_TYPE);
14. sCallsProjectionMap.put(Calls.CACHED_NUMBER_LABEL, Calls.CACHED_NUMBER_LABEL);
15. }
16.
17. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
18. String sortOrder) {
19. SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
20. int match = sURIMatcher.match(uri);
21. switch (match) {
22. case CALLS: {
23. qb.setTables("calls"); //设置表名
24. qb.setProjectionMap(sCallsProjectionMap); //设置列名映射
25. break;
26. }
27.
28. case CALLS_ID: {
29. qb.setTables("calls");
30. qb.setProjectionMap(sCallsProjectionMap);
31. qb.appendWhere("calls._id="); //构造用于查询的where子句
32. qb.appendWhere(uri.getPathSegments().get(1));
33. break;
34. }
35.
36. case CALLS_FILTER: {
37. qb.setTables("calls");
38. qb.setProjectionMap(sCallsProjectionMap);
39. String phoneNumber = uri.getPathSegments().get(2);
40. qb.appendWhere("PHONE_NUMBERS_EQUAL(number, ");
41. qb.appendWhereEscapeString(phoneNumber); //同appendWhere,可防止SQL注入
42. qb.appendWhere(mUseStrictPhoneNumberComparation ? ", 1)" : ", 0)");
43. break;
44. }
45.
46. default:
47. throw new IllegalArgumentException("Unknown URL " + uri);
48. }
49.
50. final SQLiteDatabase db = mDbHelper.getReadableDatabase();
51. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, null);
52. if (c != null) {
53. c.setNotificationUri(getContext().getContentResolver(), CallLog.CONTENT_URI);
54. }
55. return c;
56. }
注意:
qb.setProjectionMap(sCallsProjectionMap);
这个函数的作用是在qb里设置数据库字段的别名, 即用户定义列名->数据库列名,在执行qb.query时可以使用用户定义列名设置projection、selection等。
如果不需要对列名进行映射,可以不调用这个函数。但是如果调用,必须对所有列都进行映射,映射中key和value可以完全相同。以上代码中就是这样,至于为什么还要这么做,等下一步继续研究。。。