0

我目前正在实现一个 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;
                }

所以没有公共构造函数,这是访问 helper 的唯一方法。

现在我的问题是每次我尝试执行任何操作时是否应该打开数据库。例如,考虑帮助类的以下 menmber 函数:

           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;
                   }

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

4

2 回答 2

1

停止!等待!冻结!

“我目前正在实现一个 databasehalper 类,该类将从各种线程中访问,因此它基本上是单例的,并且可以像这样访问:”

你说你的 HistoryDatabaseHelper 将被不同的线程访问而你忘记同步 getInstance 方法?你的线会在他们离开家之前穿上他们的跑鞋,因为他们肯定会参加比赛。如果您希望您的线程表现得像成年人一样,您需要同步您的 getInstance 方法。或者,您可以在声明过程中实例化 mInstance 实例变量,避免同步 getInstance 或检查 mInstance 是否已经在 getInstance 中初始化。

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

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

So should you have a singleton database connection? I personally think it would be a better idea if you had a singleton database connection pool instead of a singleton database connection. A Google search will give you a lot of good libraries for connection pooling out there.

于 2012-10-05T19:34:49.850 回答
0

如果 HistoryDatabaseHelper 是线程安全的,这应该只是一个单例。调用者必须传入一个参数来获取单例的事实应该是一个很大的危险信号,因为这意味着单例的状态与这个参数有关。

从线程的角度来看,最安全的事情是让类不是单例,只需根据需要创建一个新的。如果事实证明这会减慢您的应用程序的速度,请对其进行基准测试并制定解决方案,可能使用 c3p0 等连接池等。

如果您确定 HistoryDatabaseHelper 是线程安全的,则在类中初始化单例,并且不需要任何参数来获取单例。

于 2012-10-05T16:11:29.820 回答