java - 实现单例 SqliteDatabaseHelper 类的正确方法

标签 java database concurrency android-sqlite

我目前正在实现一个databasehalper类,它将从不同的线程访问,所以它基本上是单例的,并且像这样访问:

               public class HistoryDatabaseHelper extends SQLiteOpenHelper{
                private static HistoryDatabaseHelper mInstance=null;
                public static HistoryDatabaseHelper getInstance(Context context){
            if(mInstance==null)
              mInstance=new HistoryDatabaseHelper(context.getApplicationContext());
            return mInstance;
                }

因此没有公共(public)构造函数,这是访问 helper 的唯一方法。

现在我的问题是,每次我尝试执行任何操作时都应该打开数据库吗?例如,考虑辅助类的以下成员函数:

           public void deleteContact(String staticUrl) {
           SQLiteDatabase db = this.getWritableDatabase();  // does this open a new connection each time?
                                                            //  and invade the whole purpose of 
                                                             //creating singleton helper
           db.delete(TABLE_DOWNLOAD_HISTORY, KEY_STATIC_URL + " = ?",
           new String[] { staticUrl });
           db.close();
                 }

这是正确的方法还是我应该像这样打开数据库一次:

            public static HistoryDatabaseHelper getInstance(Context context){
          if(mInstance==null){
               mInstance=new HistoryDatabaseHelper(context.getApplicationContext());
               mInstance.open();  // here
                           }
               return mInstance;
                   }

如果是这样那么我们应该在哪里关闭数据库?

最佳答案

停下来!等待!卡住!

“我目前正在实现一个databasehalper类,它将从不同的线程访问,所以它基本上是单例的,并像这样访问:”

您说您的 HistoryDatabaseHelper 将从各个线程访问,并且您忘记同步 getInstance 方法?你的线程在离开家之前会穿上跑鞋,因为他们肯定已经准备好参加比赛了。如果您希望线程像成年人一样运行,则需要同步您的 getInstance 方法。或者,您可以在声明本身期间实例化 mInstance 实例变量,并避免同步 getInstance 或检查 mInstance 是否已在 getInstance 内初始化的需要。

接下来是 HistoryDatabasrHelper 构造函数。您需要显式声明一个私有(private) HistoryDatabaseHelper 构造函数,因为否则编译器将在您的类中放置一个公共(public)构造函数。不这样做就像让你的邻居偷了你的东西而不把它们交给警察。

最后但并非最不重要的是 getInstance 方法的 Context 参数。删除该参数。让您的 HistoryDatabasrHelper 有一个 Context 实例变量,并在您的私有(private)构造函数中初始化它,假设 Context 不会从一个实例更改为另一个实例。

那么您应该有一个单例数据库连接吗?我个人认为,如果您有一个单例数据库连接池而不是单例数据库连接,那将是一个更好的主意。 Google 搜索将为您提供许多用于连接池的优秀库。

关于java - 实现单例 SqliteDatabaseHelper 类的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12749986/

相关文章:

java - StampedLock.writeLock() 是否释放当前线程持有的读锁?

java - Android Studio 中缺少可绘制文件夹

java - 使用 JDBC Statement 或PreparedStatement 执行一组查询

java - 在 Java 中,访问 RandomAccessFile 时从 FileChannel 获取 FileLock 的有保证的方法是什么?

删除在 Windows 资源管理器中打开的嵌套文件夹时的 Java 奇怪行为

php - 如何在zend-framework 2的页脚中显示动态数据

php - redis中如何使用sortable数据结构

javascript - Node 中的单例 MongoDB 连接

linux - 少数繁忙线程与许多闲置线程

c++ - Actor 模型 : Why is Erlang/OTP special? 你能用另一种语言吗?