Использование одного и того же экземпляра SQLiteDatabase в разных экземплярах SQLiteOpenHelper

Мне нужно несколько таблиц в моем приложении. Для этого я создал отдельные подклассы SQLiteOpenHelper для вставки/удаления/обновления данных для разных таблиц. Мой вопрос в том, как я могу убедиться, что все эти подклассы используют один и тот же экземпляр SQLiteDatabase во всем коде. Хотя я сделал каждый подкласс синглтоном. Однако я не мог обойти проблему использования общего экземпляра SQLiteDatabase во всем коде.

PS: я не хочу использовать ContentPovider или создавать один подкласс SQLiteOpenHelper, так как это усложнит мой код.


person Gaurav Arora    schedule 28.11.2012    source источник


Ответы (2)


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

public class SQLiteCustomBase extends SQLiteOpenHelper {

    private static final String CREATE_BDD_1 = "CREATE TABLE ...";
    private static final String CREATE_BDD_2 = "CREATE TABLE ...";

    public SQLiteCustomBase(Context context, String name, CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BDD_1);
        db.execSQL(CREATE_BDD_2);
    }

    @Override
    public void onOpen(SQLiteDatabase db) {}

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE " + Vars.TABLE_1 + ";");
        db.execSQL("DROP TABLE " + Vars.TABLE_2 + ";");
        onCreate(db);
    }
}

а затем в классе, где вы выполняете некоторые действия с базой данных:

public class HandlerClass {
    private SQLiteDatabase db;
    private SQLiteCustomBase customBase;

    public HandlerClass(Context context){
        customBase = new SQLiteCustomBase(context, Vars.NAME_DB, null, Vars.VERSION_DB);
    }

    public void open(){
        db = customBase.getWritableDatabase();
    }

    public void openForRead(){
        db = customBase.getReadableDatabase();
    }

    public void close(){
        db.close();
    }

    public SQLiteDatabase getDB(){
        return db;
    }
}

void myMethods()
{
    bdd.insert(Vars.TABLE_1, null, values);
    bdd.insert(Vars.TABLE_2, null, values);
}
etc.
person PeterGriffin    schedule 28.11.2012
comment
Спасибо. Я также сделал класс SQLiteCustomBase одноэлементным, чтобы все классы HandlerClass использовали один и тот же экземпляр SQLiteDatabase во всем приложении. Это позволяет избежать сбоев при одновременном выполнении! - person Gaurav Arora; 29.11.2012

Пока вы используете один и тот же SQLiteOpenHelper (для каждой базы данных), все будет в порядке. Он автоматически обеспечивает доступ getWriteableDatabase и getReadableDatabase только к одной кэшированной базе данных.

person yydl    schedule 28.11.2012
comment
Проблема в том, что у меня несколько таблиц. Поэтому я использую несколько экземпляров SQLiteOpenHelper для уменьшения сложности. У вас есть лучший подход? - person Gaurav Arora; 28.11.2012
comment
Да. Если вы используете несколько таблиц, но все они находятся в одной базе данных, вы должны использовать только один SQLiteOpenHelper. В противном случае вы рискуете сбоем некоторых операций записи. Проще всего использовать только помощника, который заботится об этой базе данных. - person yydl; 28.11.2012
comment
Соглашаться. Проблема здесь в том, что примеры игрушек SQLiteOpenHelper обычно получаются в грязном коде, когда вам нужны кратные таблицы, есть внешние ключи и т. д. Помощник должен знать об именах таблиц и строк для создания и обновления БД. Это слишком большая связь, и обычно появляется кошмар констант в верхней части класса. Если вы хотите использовать помощник чистым и удобным для сопровождения образом, создайте интерфейс DAO с помощью методов onCreate(SQLiteDatabase db) и onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion). Затем в помощнике введите свои DAO и обратные вызовы для каждого из них. - person Mister Smith; 28.11.2012