¿Cuál es el propósito de un mapa de proyección de Android en un proveedor de contenido?
Estoy viendo el código de ejemplo de la aplicación de bloc de notas Android en <path_to_SDK>/samples/android-16/NotePad/src/com/example/android/notepad
.
Me preguntaba si alguien podría explicarme por qué el siguiente código es necesario en NotepadProvider.java
?
- IllegalStateException: base de datos ya cerrada (con ViewPager)
- ¿Cómo recargar / refrescar el fragmento que ya se ha mostrado una vez?
- Android: ¿Qué hace ContentResolver.update () hacer excactly?
- No se puede ejecutar la consulta de eliminación correctamente usando rawQuery
- Android SQLite issue - table ... no tiene una columna llamada
// 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)
Observo que el mapa de proyección se utiliza más adelante en el método 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; ...
¿Por qué se necesita este mapa de proyección?
- Un comportamiento extraño para reguelr sqlite operación en android
- Cómo importar la biblioteca Persistence Room a un proyecto de Android
- Código de error SQLite 17
- Cómo obtener id de la base de datos al hacer clic en el elemento listview en android
- Insertar datos JSON en la base de datos SQLite en android
- Actualizar la base de datos Sqlite en android?
- Actualización de base de datos y aplicaciones Android SQLite
- ¿Qué tipos de caché realiza SQLite en Android?
La aplicación Notepad
de las demostraciones de SDK
es una aplicación de ejemplo, que debería ser un ejemplo de uso de API y buenas prácticas que utilizan esas API, por eso es probable que utilicen un mapa de proyección. Aunque la muestra del Notepad
realmente no necesita un mapa de proyección, el uso de uno es un buen escaparate para casos más complejos cuando uno es necesario. Por ejemplo, si recuerdo bien, la aplicación de Shelves
escrita por uno de los ingenieros de Google está usando un mapa de proyección en su ContentProvider
y ese mapa de proyección no es sólo una asignación simple con pares clave-valor idénticos.
También he añadido un enlace a la documentación del método SQLiteQueryBuilder.setProjectionMap
que tiene algunos detalles sobre por qué se necesita un mapa de proyección.
Su propósito principal es renombrar los nombres de columna encontrados en un cursor producido por una consulta.
@static declaration
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" );
@ Su funcionalidad de consulta
//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 );
Las columnas devueltas ahora son _name y _id en este ejemplo.
Además de lo que dijo Juan, el propósito del mapa de proyección es para cambiar el nombre de las columnas, así como desambiguar los nombres de las columnas al hacer las uniones, el propósito importante de los mapas de proyección es verificar la selección contra los argumentos maliciosos.
Cuando se utiliza SQLiteQueryBuilder
para crear una sentencia utilizando buildQueryString(boolean, String, String[], String, String, String, String, String)
, si se especifica un mapa de proyección, los campos que no estén en ese mapa serán ignorados.
Para obtener la máxima protección contra aplicaciones de terceros maliciosas (por ejemplo, los proveedores de proveedores de contenido), puede hacer lo siguiente:
- Establecer
SQLiteQueryBuilder#setStrict(true)
- Utilice un mapa de proyección.
- Utilice una de las sobrecargas de consulta en lugar de obtener la sentencia como una cadena SQL
Tal vez alguien necesita una explicación más completa. He reunido datos importantes sobre el mapa de proyección:
-
Si no necesita un mapa de proyección, no lo configure. De esta manera, los nombres de las proyecciones se procesan "tal cual", exactamente como se pasa a través de la matriz de proyección.
-
Incluso la matriz de proyección es opcional. Si pasa null a la consulta, genera una operación "SELECT *". (En realidad eso no se recomienda en SQL, debido a la rotura que puede ocurrir si las columnas se agregan / quitan o vuelven a ordenar).
-
El mapa de proyección suministrado sólo se aplica a la lista de selección. Por lo tanto, podría asignar "store_name" => "bookstore.storename", y resultaría en "select bookstore.storename …", pero si proporcionó "store_name" en el parámetro "order by" o uno de Los otros parámetros calificados, potencialmente puede terminar con SQL mal.
-
El mapa de proyección puede ser anulado. Si la parte clave de una entrada de proyección contiene una cláusula "as", la parte de valor se ignora y la parte clave se inserta en el SQL resultante. Por ejemplo "loro como polly" => "cracker" generará "SELECT loro como polly …" y no "cracker". El "como" puede ser en mayúsculas o en minúsculas (no en caso mixto) y debe tener al menos un espacio antes y después de la palabra "como".
Lea más información en este artículo: http://www.mousetech.com/blog/android-projection-maps-explained/