Подтвердить что ты не робот

Какова цель карты проекции Android в контент-провайдере?

Я рассматриваю пример кода приложения для блокнота Android в <path_to_SDK>/samples/android-16/NotePad/src/com/example/android/notepad.

Мне было интересно, может ли кто-нибудь объяснить мне, зачем нужен следующий код в 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;
...

Зачем нужна карта проекций?

4b9b3361

Ответ 1

Приложение Notepad из демонстраций SDK является примером приложения, которое должно быть примером использования API и передовой практики с использованием этих API-интерфейсов, поэтому они, вероятно, используют карту прогноза. Хотя образец Notepad действительно не нужен проекционная карта, использование одного из них является хорошей демонстрацией для более сложных случаев, когда это необходимо. Например, если я правильно помню, приложение Shelves, написанное одним из инженеров Google, использует карту проецирования в своем ContentProvider, и эта проекционная карта - это не просто сопоставление с идентичными парами ключ-значение.

Я также добавил ссылку на документацию по методу SQLiteQueryBuilder.setProjectionMap, в котором есть некоторые сведения о том, почему вам нужна проекционная карта.

Ответ 2

Его основная цель - переименовать имена столбцов, найденные в курсоре, создаваемом запросом.

@статическая декларация

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

Функциональность вашего запроса

//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 в этом примере.

Ответ 3

В дополнение к тому, как сказал Хуан, целью проекционной карты является переименование имен столбцов, а также устранение неоднозначности имен столбцов при выполнении объединений, важная цель проекционных карт - проверка выбора против вредоносных аргументов.

При использовании SQLiteQueryBuilder для создания оператора с использованием buildQueryString(boolean, String, String[], String, String, String, String, String), если указана карта проекции, поля, не содержащие эту карту, будут игнорироваться.

Чтобы получить максимальную защиту от вредоносных сторонних приложений (например, потребителей контент-провайдера), вы можете сделать следующее:

  • Установить SQLiteQueryBuilder#setStrict(true)
  • Используйте карту проецирования.
  • Используйте одну из перегрузок запросов вместо получения инструкции как Строка sql

Ответ 4

Возможно, кому-то нужно более подробное объяснение. Я собрал важные факты о проекционной карте:

  • Если вам не нужна карта проекции, просто не устанавливайте ее. Таким образом, проекционные имена обрабатываются "как есть", точно так же, как переданные через проекционный массив.

  • Даже проекционный массив не является обязательным. Если вы передаете null в запрос, он генерирует операцию "SELECT *". (на самом деле это не рекомендуется в SQL, из-за поломки, которая может возникнуть, если столбцы добавлены/удалены или переупорядочены).

  • Прилагаемая карта проекции относится только к списку выбора! Таким образом, вы можете сопоставить "store_name" = > "bookstore.storename", и это приведет к "select bookstore.storename...", но если вы указали "store_name" в параметре "order by" query builder или один из другие квалифицированные параметры, вы можете в конечном итоге с плохим SQL.

  • Карта проекции может быть переупорядочена. Если ключевая часть записи проекции содержит предложение "как", часть значения игнорируется, а ключевая часть вставляется в результирующий SQL. Например, "попугай, как польский" = > "взломщик" будет генерировать "SELECT попугай, как политический...", а не "взломщик". "As" может быть либо в верхнем регистре, либо в любом нижнем регистре (не смешанный случай) и должен иметь по крайней мере одно пространство до и после слова "как".

Подробнее читайте в этой статье: http://www.mousetech.com/blog/android-projection-maps-explained/