Intereting Posts
Обфускация кода Android с помощью ProGuard … как узнать, что он был запутан? Вызвано: android.os.NetworkOnMainThreadException CREATE TABLE Ошибка android_metadata завершилась неудачей при повторном открытии sqlcipher DB ProGuard вызывает SSL-квитирование на Android Есть ли хорошие примеры коротких кодов, которые просто читают новое сообщение Gmail? XML-ориентированные графические интерфейсы и производительность Запретить перезагрузку активности при нажатии на SearchView Рисование 9-патча на холсте с помощью drawBitmap Недопустимое исключение аргумента в диалоговом окне андроида Android: загрузка файла с защитой от NTLM-аутентификации GetFragmentManager.findFragmentByTag () возвращает null Как узнать размер файла перед его загрузкой? Как установить конкретную вкладку при открытии активности макета макета? ASIHTTPRequest эквивалент для Android или любого HTTP-менеджера запросов / обертки? Android Studio не отображает макет

Android: ContentProvider для каждой таблицы / обработки отношений «один ко многим»

При использовании поставщика контента для доступа к базе данных SQLite

  1. Лучше ли практика иметь поставщика контента для каждой таблицы или использовать ее для всех таблиц?
  2. Как обрабатывать отношения «один ко многим» при создании новых записей?

Solutions Collecting From Web of "Android: ContentProvider для каждой таблицы / обработки отношений «один ко многим»"

ContentProvider не является базой данных

ContentProvider – это способ публично (или полупублично) доступа к данным в качестве контента. Это можно сделать несколькими способами: через доступ к файлам, SQLite или даже доступ к сети. ContentProvider сам по себе не является базой данных, но вы можете запрограммировать для нее базу данных. У вас может также быть несколько ContentProviders, которые обращаются к одной и той же базе данных, но распределяют различные уровни доступа или же содержимое по-разному в зависимости от запрашивающего.

То, что вы действительно задаете, не является вопросом ContentProvider, а вопросом базы данных «Как обрабатывать отношения в базе данных SQLite», потому что ContentProvider не использует код базы данных, если вы не скажете его через SQLiteOpenHelper и другие подобные классы. Таким образом, вам просто нужно правильно запрограммировать доступ к базе данных, и ваша база данных SQLite будет работать по своему желанию.

База данных – это база данных

В прежние времена базы данных были просто плоскими файлами, где каждая таблица часто являлась собственной сущностью, чтобы обеспечить рост. Теперь, с СУБД, очень мало оснований для этого. SQLite подобен любой другой платформе базы данных в этом отношении и может содержать столько таблиц, сколько у вас есть места для их хранения.

SQLite

Есть некоторые функции, которые SQLite хорошо обрабатывает, некоторые из них обрабатываются – но не очень хорошо, а некоторые из них вообще не обрабатываются. Отношения – это одна из тех вещей, которые были исключены из некоторых версий SQLite от Android, поскольку они поставлялись без поддержки внешнего ключа. Это была очень запрошенная функция, и она была добавлена ​​в SQLite 3.6.22, которая не отправлялась до Android 2.2. Тем не менее, все еще есть много сообщений об ошибках, но в самых ранних воплощениях.

Android до 2.2

К счастью, будучи совместимым с SQL и простой СУБД (а не RDBMS в это время), есть несколько простых способов обойти это, в конце концов, внешний ключ – это просто поле в другой таблице.

  1. Вы можете применять INSERT базы данных и UPDATE , создавая CONSTRAINT при использовании инструкции CREATE TABLE .
  2. Вы можете запросить другую таблицу для соответствующего _id чтобы получить свой внешний ключ.
  3. Вы можете запросить свою исходную таблицу любым соответствующим SELECT с помощью INNER JOIN , тем самым обеспечив псевдосвязь.

Поскольку версия SQLite от Android не обеспечивает прямое соблюдение отношений, если вы хотите использовать CASCADE ON DELETE вам придется делать это вручную. Но это можно сделать с помощью другого простого оператора SQL. Я по существу написал свою собственную библиотеку, чтобы обеспечить соблюдение таких отношений, поскольку все это нужно делать вручную. Однако я должен сказать, что эффективность SQLite и SQL в целом делает это очень быстрым и легким.

По сути, процесс любых принудительных отношений выглядит следующим образом:

  • В запросе, который требует внешний ключ, используйте JOIN .
  • В INSERT используйте CONSTRAINT для поля внешнего ключа NOT NULL
  • В UPDATE в поле первичного ключа, являющемся внешним ключом в другой TABLE , запустите второй UPDATE в соответствующем TABLE который имеет внешний ключ. (ОБНОВЛЕНИЕ КАСКАДА)
  • Для DELETE с теми же параметрами выполните еще один DELETE где будет foreign_key = _id (убедитесь, что вы получили _id перед тем, как вы DELETE строку, сначала).

Android 2.2+

Внешние ключи поддерживаются, но по умолчанию отключены. Сначала вам нужно включить их:

 db.execSQL("PRAGMA foreign_keys=ON;"); 

Затем вы должны создать связь TRIGGER . Это делается при создании TABLE , а не отдельного оператора TRIGGER . Смотри ниже:

 // Added at the end of CREATE TABLE statement in the MANY table FOREIGN KEY(foreign_key_name) REFERENCES one_table_name(primary_key_name) 

Для получения дополнительной информации о SQLite и его возможностях посетите официальный сайт SQLite . Это важно, поскольку у вас нет всех JOIN которые вы делаете в других СУБД. Для получения конкретной информации о классах SQLite в Android прочитайте документацию .

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

Поставщик контента примерно эквивалентен концепции базы данных. У вас будет несколько таблиц в базе данных, поэтому наличие нескольких таблиц в вашем контент-провайдере имеет смысл.

От одного до многих отношений можно обращаться так же, как в любой другой базе данных. Используйте ссылки и внешние ключи, как и с любой другой базой данных. Вы можете использовать такие вещи, как CASCADE ON DELETE, чтобы убедиться, что записи удалены, когда записи, которые они ссылаются в других таблицах, также удаляются.