【问题标题】:Correctly open/close a database with Singleton design pattern使用单例设计模式正确打开/关闭数据库
【发布时间】:2013-07-24 12:48:24
【问题描述】:

我正在创建一个与数据库进行大量交互(读取和写入操作)的应用程序。

为了避免在每次请求时进行打开/关闭操作,我创建了一个扩展 SQLiteOpenHelper 的类,它采用单例设计模式。这样,我确信在所有 application 生命周期(而不仅仅是 activity 生命周期)中,只有一个 SQLiteOpenHelper 实例和一个与数据库的连接。

我也阅读了一些关于 ContentProvider 的文章,但我不确定这是一个更好的方法。

所以,这是我的 Singleton 类的主要逻辑(onCreateonUpgrade 已删除):

public final class BaseSQLite extends SQLiteOpenHelper {

    private static BaseSQLite mInstance = null;

    private SQLiteDatabase db = null;

    public static BaseSQLite getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new BaseSQLite(context.getApplicationContext(),
                    DBNAME, DBVERSION);
        }
        return mInstance;
    }

    private BaseSQLite(final Context context, final String name,
            final int version) {
        super(context, name, null, version);
        db = getWritableDatabase();
    }

    @Override
    public synchronized void close() {
        if (mInstance != null)
            db.close();
    }

    public Cursor getAllData() {
        String buildSQL = "SELECT * FROM myTable";

        return db.rawQuery(buildSQL, null);
    }

}

所以,为了访问我的数据库,我做了这个:

BaseSQLite baseSQLite = BaseSQLite.getInstance(context);
baseSQLite.getAllData();

它现在完美运行。但我的问题是关于close() 方法。我真的不知道什么时候打电话。实际上,我的数据库实例对于我的应用程序的每个 Activies 都是相同的,所以我认为在 onPause() 方法中调用 close() 是一个坏主意,因为该实例可能(并且经常会发生)在onStart() 下一个 Activity 的方法。此外,我无法检测到我的应用程序的end,即当屏幕上不再可见活动时。

有人可以帮我解决这个问题吗?当数据库链接到 ONE 活动时,我找到了一些答案,但没有为我的案例提供真正的提示。

【问题讨论】:

    标签: android android-sqlite android-lifecycle sqliteopenhelper


    【解决方案1】:

    您应该在完成对数据库的写入后调用 close。例如,当您插入数据时,您将与数据库建立一个打开的连接,完成后应该关闭该连接。

    阅读是不同的。当您在手机上创建 SQLite 数据库时,数据是持久的。数据库存在,您创建的处理程序提供了访问该信息的便捷方式。读取数据库通常通过获取数据库的可读实例并使用Cursor 来提取值来进行。在这种情况下,您在完成后关闭光标,而不是数据库本身。

    您是对的,您不应该在单独活动的生命周期方法期间关闭数据库连接。相反,如上所述,当您完成执行该事务时,请关闭写入数据库的处理程序方法中的数据库连接。

    【讨论】:

    • 好的,所以我必须删除行db = getWritableDatabase(),并在每个方法中添加getWritableDatabase()getReadableDatabase()。然后,在写作方法中,比如updateEntry(Object),我应该写成这样:getWritableDatabase(); db.rawQuery(myRequestString, null); db.close()?
    • 如果 myRequestString 是一个插入语句 - 是的。 look at this example 我不建议您完全复制,但您可以看到关闭在事务中的工作方式。我这样做的方法是在执行每个写入功能的 db 处理程序类中有一个方法 - 例如向表中添加条目。在该方法的开始,我得到一个可写的数据库实例,当事务完成后,我在方法结束时关闭它。
    • 好的。这似乎是一个非常好的选择。我担心表演会打出很多开/关电话,但显然这不是一个真正的问题:)
    • "你应该在写完数据库后调用 close" 不,你不应该
    • 完全错误。请再做一次搜索,即使谷歌文档也说最好让它保持打开状态并让 GC 关闭它,而不是在每次操作时重新打开它。 stackoverflow.com/questions/6608498/…
    猜你喜欢
    • 1970-01-01
    • 2010-09-13
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    相关资源
    最近更新 更多