13 votes

À quoi sert une carte de projection Android dans un fournisseur de contenu ?

Je regarde l'exemple de code de l'application Bloc-notes Android dans le site Web de la Commission européenne. <path_to_SDK>/samples/android-16/NotePad/src/com/example/android/notepad .

Je me demandais si quelqu'un pouvait m'expliquer pourquoi le code suivant est nécessaire dans le fichier 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)

Je remarque que la carte de projection est utilisée plus tard dans l'article. query() méthode :

...
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;
...

Pourquoi cette carte de projection est-elle nécessaire ?

10voto

Luksprog Points 52767

El Notepad de l'application de la SDK demos est une application d'exemple, une application qui devrait être un exemple d'utilisation des API et de bonnes pratiques d'utilisation de ces API, c'est pourquoi ils utilisent probablement une carte de projection. Bien que le Notepad L'échantillon n'a pas vraiment besoin d'une carte de projection ; son utilisation est une bonne vitrine pour les cas plus complexes où elle est nécessaire. Par exemple, si je me souviens bien, la Shelves L'application écrite par l'un des ingénieurs de Google utilise une carte de projection dans sa base de données. ContentProvider et que la carte de projection n'est pas qu'un simple mappage avec des paires clé-valeur identiques.

J'ai également ajouté un lien vers la documentation de la méthode SQLiteQueryBuilder.setProjectionMap qui explique en détail pourquoi vous avez besoin d'une carte de projection.

9voto

juanmendezinfo Points 6

Son but principal est de renommer les noms de colonnes trouvés dans un curseur produit par une requête.

Déclaration statique

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" );  

@votre fonctionnalité de requête

//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 );

les colonnes retournées sont maintenant _name et _id dans cet exemple.

0voto

En plus de ce que Juan a dit, le but de la carte de projection est de renommer les noms de colonnes ainsi que de désambiguïser les noms de colonnes lors des jointures, le but important des cartes de projection est de vérifier la sélection contre les arguments malveillants.

Lorsque vous utilisez SQLiteQueryBuilder pour créer une déclaration utilisant buildQueryString(boolean, String, String[], String, String, String, String, String) si une carte de projection est spécifiée, les champs qui ne figurent pas dans cette carte seront ignorés.

Pour obtenir une protection maximale contre les applications tierces malveillantes (par exemple les consommateurs de fournisseurs de contenu), vous pouvez procéder comme suit :

  1. Définir SQLiteQueryBuilder#setStrict(true)
  2. Utilisez une carte de projection.
  3. Utilisez l'une des surcharges de requête au lieu de récupérer la déclaration sous forme de chaîne sql

0voto

zkvarz Points 386

Peut-être que quelqu'un a besoin d'une explication plus approfondie. J'ai rassemblé des faits importants sur la carte de projection :

  1. Si vous n'avez pas besoin d'une carte de projection, ne la définissez pas. De cette façon, les noms de projection sont traités "tels quels", exactement comme ils sont passés dans le tableau de projection.

  2. Même le tableau de projection est facultatif. Si vous passez null à la requête, elle génère une opération "SELECT *". (en fait, ce n'est pas recommandé en SQL, à cause de la rupture qui peut se produire si des colonnes sont ajoutées/supprimées, ou réordonnées).

  3. La carte de projection fournie s'applique uniquement à la liste de sélection ! Ainsi, vous pouvez mapper "store_name" => "bookstore.storename", et le résultat sera "select bookstore.storename ...", mais si vous avez fourni "store_name" dans le paramètre de construction de requête "order by" ou l'un des autres paramètres qualifiés, vous pouvez potentiellement vous retrouver avec un mauvais SQL.

  4. La carte de projection peut être annulée. Si la partie clé d'une entrée de projection contient une clause "as", la partie valeur est ignorée et la partie clé est insérée dans le SQL résultant. Par exemple "parrot as polly" => "cracker" générera "SELECT parrot as polly ..." et pas de "cracker". Le mot "as" peut être soit tout en majuscules, soit tout en minuscules (pas de mélange de majuscules et de minuscules) et doit comporter au moins un espace avant et après le mot "as".

Pour en savoir plus, lisez cet article : http://www.mousetech.com/blog/Android-projection-maps-explained/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X