我正在查看<path_to_SDK>/samples/android-16/NotePad/src/com/example/android/notepad
中的Android记事本应用示例代码。
我想知道是否有人可以向我解释为什么NotepadProvider.java
中需要以下代码?
// Creates a new projection map instance. The map returns a column name
// given a string. The two are usually equal.
sNotesProjectionMap = new HashMap<String, String>();
// Maps the string "_ID" to the column name "_ID"
sNotesProjectionMap.put(NotePad.Notes._ID, NotePad.Notes._ID);
// Maps "title" to "title"
sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_TITLE,NotePad.Notes.COLUMN_NAME_TITLE);
// Maps "note" to "note"
sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_NOTE, NotePad.Notes.COLUMN_NAME_NOTE);
// Maps "created" to "created"
sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, NotePad.Notes.COLUMN_NAME_CREATE_DATE);
// Maps "modified" to "modified"
sNotesProjectionMap.put(
NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE,
NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE)
我注意到投影贴图稍后在query()
方法中使用:
...
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(NotePad.Notes.TABLE_NAME);
/**
* Choose the projection and adjust the "where" clause based on URI pattern-matching.
*/
switch (sUriMatcher.match(uri)) {
// If the incoming URI is for notes, chooses the Notes projection
case NOTES:
qb.setProjectionMap(sNotesProjectionMap);
break;
...
为什么需要这个投影图?
答案 0 :(得分:10)
Notepad
演示中的SDK
应用程序是一个示例应用程序,应该是API使用示例和使用这些API的良好实践,这就是他们可能使用投影映射的原因。虽然Notepad
示例并不真正需要投影贴图,但如果需要投影贴图,则使用一个投影贴图可以很好地展示更复杂的情况。例如,如果我没记错的话,其中一位Google工程师编写的Shelves
应用程序正在其ContentProvider
中使用投影地图,该投影地图不仅仅是具有相同键值的简单映射对
我还添加了方法SQLiteQueryBuilder.setProjectionMap
文档的链接,其中详细说明了为什么需要投影图。
答案 1 :(得分:7)
其主要目的是重命名由查询生成的游标中的列名。
@static声明
SEARCH_PROJECTION_MAP = new HashMap<String, String>();
SEARCH_PROJECTION_MAP.put( OpenHelper.NAME, OpenHelper.NAME + " as _name" );
SEARCH_PROJECTION_MAP.put( OpenHelper.ID , OpenHelper.ID + " as _id" );
@your查询功能
//if you query using sqliteQueryBuilder then
sqLiteQueryBuilder.setProjectionMap( SEARCH_PROJECTION_MAP );
//example if you just query
Cursor cursor = sqLiteQueryBuilder.query( db, projection, selection, selectionArgs, null, null, sortOrder );
在此示例中,返回的列现在是_name和_id。
答案 2 :(得分:0)
除了Juan说,投影图的目的是重命名列名以及在进行连接时消除列名称的歧义,投影图的重要目的是验证选择是否与恶意参数有关。
使用SQLiteQueryBuilder
使用buildQueryString(boolean, String, String[], String, String, String, String, String)
创建语句时,如果指定了投影地图,则不会忽略该地图中的字段。
要获得针对恶意第三方应用(例如内容提供商消费者)的最大保护,您可以执行以下操作:
SQLiteQueryBuilder#setStrict(true)
答案 3 :(得分:0)
也许有人需要更彻底的解释。我收集了关于投影图的重要事实:
如果您不需要投影地图,请不要设置它。这样,投影名称将“按原样”处理,与通过投影数组传递完全相同。
即使是投影阵列也是可选的。如果将null传递给查询,则会生成“SELECT *”操作。 (实际上这不是在SQL中推荐的,因为如果添加/删除或重新排序列可能会发生破坏。)
提供的投影图仅适用于选择列表!所以,你可以映射“store_name”=&gt; “bookstore.storename”,它会导致“select bookstore.storename ...”,但如果您在“order by”查询构建器参数或其他一个合格参数中提供了“store_name”,则可能最终错误的SQL。
可以推翻投影地图。如果投影条目的关键部分包含“as”子句,则忽略值部分,并将关键部分插入到生成的SQL中。例如“parrot as polly”=&gt; “cracker”将产生“SELECT polrot as polly ......”而不会产生“cracker”。 “as”既可以是大写也可以是全部小写(不是混合大小写),并且必须在单词“as”之前和之后至少有一个空格。
阅读本文中的更多信息: http://www.mousetech.com/blog/android-projection-maps-explained/