【问题标题】:Using same instance of SQLiteDatabase across different instances of SQLiteOpenHelper在 SQLiteOpenHelper 的不同实例中使用相同的 SQLiteDatabase 实例
【发布时间】:2012-11-28 14:09:00
【问题描述】:

我的应用程序中需要多个表。为此,我创建了 SQLiteOpenHelper 的单独子类来插入/删除/更新不同表的数据。我的问题是如何确保所有这些子类在整个代码中使用 SQLiteDatabase 的相同实例。尽管我已将每个子类设为单例。但是,我无法解决在整个代码中使用通用 SQLiteDatabase 实例的问题。

PS:我不想使用 ContentPovider 或创建单个 SQLiteOpenHelper 子类,因为这会使我的代码复杂化。

【问题讨论】:

    标签: android multithreading sqlite singleton sqliteopenhelper


    【解决方案1】:

    只要您在整个(每个数据库)都使用相同的 SQLiteOpenHelper,就可以了。它会自动确保 getWriteableDatabase 和 getReadableDatabase 只访问一个缓存数据库。

    【讨论】:

    • 问题是我有多个表。因此,我使用多个 SQLiteOpenHelper 实例来降低复杂性。你有更好的方法吗?
    • 是的。如果您使用多个表但它们都在同一个数据库中,那么您绝对应该只使用一个 SQLiteOpenHelper。否则,您将面临某些写入失败的风险。最简单的方法是仅在处理该数据库的助手上使用。
    • 同意。这里的问题是,当您需要多个表并且有外键等时,SQLiteOpenHelper 玩具示例通常会在脏代码中派生。助手需要了解表名和行名以创建和升级数据库。那是太多的耦合,通常会出现类顶部常量的噩梦。如果您想以干净且可维护的方式使用帮助程序,请使用 onCreate(SQLiteDatabase db)onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 方法创建一个 DAO 接口。然后在 helper 中注入你的 DAO 并回调到每一个
    【解决方案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.
    

    【讨论】:

    • 谢谢。我还将SQLiteCustomBase 类设为单例,以便所有HandlerClass 在整个应用程序中使用SQLiteDatabase 的相同实例。这避免了同时执行期间的任何崩溃!
    猜你喜欢
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多