Можно ли использовать статический класс «Хелпер базы данных»? - PullRequest
5 голосов
/ 27 февраля 2011

У меня есть несколько проектов Android , и большинство из них связаны с базами данных SQLite .Меня интересует, является ли хорошей практикой программирования (или плохим привычкой) использование некоторого статического класса, такого как " DatabaseHelper.class ", в котором у меня есть все статические методы, связанные с манипулированием базой данных.Например,

public static int getId(Context context, String name) {
    dbInit(context);

    Cursor result = db.rawQuery("SELECT some_id FROM table WHERE some_name = '" + name + "'", null);
    result.moveToFirst();
    int id = result.getInt(result.getColumnIndex("some_id"));
    result.close();

    return id;
}

, где dbInit (контекст) (который используется во всех моих статических методах для манипулирования базой данных) равно

private static void dbInit(Context context) {
    if (db == null) {
        db = context.openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE, null);
    }
}

Затем, когда мне что-то нужно, я могу легко вызвать эти методы, например, с помощью

int id = DatabaseHelper.getId(this, "Abc");

РЕДАКТИРОВАТЬ: Нужно ли использовать dbClose для каждого соединения или оставить его открытым?активность и близкая активность?Так я должен изменить этот верхний код на что-то вроде этого?

    ...
    dbClose();

    return id;
}

private static void dbClose() {
    if (db != null) {
        db.close();
    }
}

Ответы [ 3 ]

6 голосов
/ 27 февраля 2011

Я бы предложил вам привыкнуть к соединению с базой данных каждый раз, когда вам это нужно, и освобождать его, когда закончите с ним. Обычное название для такого объекта - «пул соединений с базой данных».

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

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

5 голосов
/ 27 февраля 2011

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

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

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

public class MyActivity extends Activity {    
  private DBAccess dbAccess;
  public MyActivity() {
     dbAccess = new DBAccess(this);
  }    
}

В качестве второго шага вы можете захотеть исследовать такие фреймворки, как RoboGuice для преодоления жесткой зависимости.Ваш код будет выглядеть примерно так:

public class MyActivity extends Activity {    
  @Inject private DBAccess dbAccess;
  public MyActivity() {
  }    
}

Дайте нам знать, если вы хотите получить более подробную информацию!

0 голосов
/ 27 февраля 2011

Если вы собираетесь использовать синглтон, минимальное требование - сделать его не имеющим состояния / безопасным для потоков. Если вы используете свой метод getId в том виде, в котором он существует, одновременные вызовы могут привести к различным странным ошибкам ...

dbInit(context);

Может быть вызван для потока A, который затем останавливает обработку перед выполнением запроса. Впоследствии поток B выполняет getId, а также вызывает dbInit, передавая в другом контексте все вместе. Затем поток A возобновит работу и попытается выполнить запрос в контексте B.

Возможно, это не проблема в вашем приложении, но я бы порекомендовал прикрепить синхронизированный модификатор к этому методу getId!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...