Intereting Posts
Вложенные фрагменты исчезают во время переходной анимации Удалить подчеркивание из ссылок в TextView – Android Как предотвратить автоматическое направление текста справа налево для иврита и арабского? SwipeListView одновременно открывается только один элемент Настроить Android на eclipse, но не знаете каталог SDK Сбросить максимальное количество текстовых просмотров Android Элементы меню должны указывать заголовок Если активность убита, работает ли AsyncTask? Значок ActionBarDrawerToggle отсутствует при использовании AppCompat v22 Android.database.sqlite.SQLiteCantOpenDatabaseException: неизвестная ошибка (код 14): не удалось открыть базу данных Android добавляет расстояние ниже последнего элемента в recyclerview с помощью gridlayoutmanager Обновление конфликта версий для игровых сервисов 9.4.0 Android studio 2.2 Столбец «приложение» Android logcat всегда пуст Когда использовать CheckBox и когда коммутатор Дизайн фрагмента: Адаптация к нескольким макетам экрана путем отображения / скрытия фрагментов в рамках одного действия?

Мой класс, полученный из SQLiteOpenHelper, становится огромным

Мой класс, полученный из SQLiteOpenHelper становится все больше и больше за время. В разное время это более 1500 строк кода, который не считается прохладным. Там может быть какое-то изящное решение, чтобы предотвратить его рост, т.е. разделение на части. Не знаю, каковы эти миры. Некоторые люди говорят, что это плохая практика, чтобы наследовать от упомянутого класса, потому что это приводит к неправильному поведению к процедурам создания / обновления базы данных. Любой намек? Большое спасибо!

Solutions Collecting From Web of "Мой класс, полученный из SQLiteOpenHelper, становится огромным"

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

Это то, что я использую:

  public interface DataAccessObject<E> { public void onCreate(SQLiteDatabase db); public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion); public void create(E... params); public E[] retrieve(E... params); public void update(E... params); public void delete(E... params); } 

Затем я кодирую реализацию для каждой таблицы. Типичным типом E обычно являются pojos. Заметьте, что я не смешиваю классы, предназначенные для хранения данных (pojos) с классами, отвечающими за сохраняющие данные (DAO's). Например, pojo может быть Car , с его переменными (цвет, год и т. Д.). Затем я бы закодировал CarDAO, расширяющий DataAccessObject<Car> . И этот класс DAO отвечает за сопоставление переменных pojo с столбцами DB, запросы к таблице и запись на нее.

Наконец, вы можете иметь SQLiteOpenHelper, который вводится DAO и делегирует материал для каждой таблицы. Эти реализации DAO – это те, у которых есть константы имен таблиц и столбцов. И они могут разговаривать друг с другом, если это необходимо для некоторых сложных запросов. (Обратите внимание, что это также является одним из недостатков этого подхода: создание аккуратного дизайна не является простым, когда вам нужны запросы, включающие множество таблиц и столбцов).

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

  • Например, вы можете думать об Active Record , где у вас есть ваши бизнес-объекты, с его полями и методами, а также со всеми методами, связанными с устойчивостью (чтение и запись из базы данных).
  • Кроме того, вы можете думать о легком объекте и сохранять экземпляры и извлекать их из базы данных другим объектом, который предоставляет возможности отображения, такой менеджер сущностей, как и некоторые ORM.
  • Вы также можете взглянуть на Zend TableGateway, что его классный подход к представлению таблиц базы данных как объектов, которые вы переносите на андроид и sqlite.
  • Вы можете использовать простое и вместе с тем мощное решение, основанное на гидраторах, как я объясняю ниже

Лично я предпочитаю использовать Hydrators

Это концепция, широко используемая в некоторых ORM, также в собственной Zend Framework и в других системах для обеспечения непрерывности данных, то есть для того, чтобы помочь объектам или даже веб-формам сопоставляться с записями базы данных в удобном для понимания и поддерживающем режиме ,

Гидратор – это объект, который сопоставляет имена полей базы данных с одной стороны, с свойствами объекта на другом. Он не хранит эту информацию внутренне, но предоставляет механизмы как для создания объектов из баз данных, так и для извлечения наборов данных из объектов для обновления базы данных.
Это то, что можно начинать так же просто, как объект с массивом имен столбцов -> Свойства сущностей, а когда YourClass hydrate() его YourClass hydrate() , будет передавать соответствующую информацию из источника данных объекту модели и когда extract(YourClass yourObject) , он переносит данные, содержащиеся в вашем объекте, в соответствующую запись базы данных

Мне очень нравится этот подход, так как очень просто создать интерфейс и несколько реализаций для случаев общего использования. Таким образом, вы можете выполнять изменения в своей базе данных, не затрагивая основные объекты или помощника . Кроме того, используя тот же интерфейс, вы можете создавать карты для экспорта ваших данных в json, xml, rest calls или любые другие вещи, которые вы можете себе представить .

Если вы можете подумать о хорошем гидраторе, а затем создать некоторые классы для наследования, вы можете иметь действительно небольшой базовый уровень базы данных, действительно небольшие объекты объекта, некоторые абстрактные классы, выполняющие общую работу, и некоторые конкретные гидраторы, которые могут получить весь вес, который вы Может понадобиться, но не так много, поскольку вы можете иметь один для каждого типа таблицы или объекта, поэтому классы кажутся меньше, и, кроме того, они содержат только код, который связан на уровне бизнеса.

Ваш помощник не должен быть такого размера. Я могу только предположить, что вы помещаете весь код, который манипулирует данными в ваш помощник.

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

Например, если у вас есть класс «Контакты». Вы бы поставили код, который сохранил контакт с базой данных в нем.

Посмотреть мой пост здесь

Я следую приведенному фрагменту кода:

Класс SQLHelper:

  public class SQLHelper extends SQLiteOpenHelper { public SQLHelper(Context context, String DBName) { super(context, DBName, null, DATABASE_VERSION); } public SQLiteDatabase getDBObject(int isWrtitable) { return (isWrtitable == 1) ? this.getWritableDatabase() : this.getReadableDatabase(); } @Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); onCreate(db); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(TABLE_1); db.execSQL(TABLE_2); ... db.execSQL(TABLE_N); } } 

MySQLManager: Что делает большая часть работы:

  public class MySQLManager { private SQLHelper sqlHelper; //Singlton class public void initMySQLManager(Context context, String DBName) { _context = context; sqlHelper = new DBHandler(context, DBName); } public MyObject getMyObjectRecord() { MyObject myObj = new MyObject(); Cursor cursor = null; try { cursor = dbObject.getWritableDatabase().rawQuery("select * FROM " + SQLHelper.MYOBJECT_TABLE + ";", null); //fetch things } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } return bookVo; } //Similarly other methods. } 

Вы можете рассматривать одноэлементный класс только для открытия и закрытия соединения db (или catch, release, как пул), а затем выполнения операций db с классом команд, как в командной строке

И вы можете использовать шаблон фасада для объединения этих команд в порядке выполнения для более сложных операций с базой данных. Это сделает ваш код чистым и простым в управлении. Например, когда вы меняете свой класс InsertBookCommand , все связанные с ним операции изменят поведение из-за него.

Подводя итог, мое решение:

Откройте соединение db и передайте db как параметр в команды. Затем выполните команды.