简体   繁体   中英

Proper way of implementing a singleton SqliteDatabaseHelper class

I am currently implementing a databasehalper class which will be accessed from various threads so it'll basically be singleton and accessed like this :

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

So there is no public constructor and this is the only way of accessing the helper .

Now my question is that should i open the database everytime i try to perform any operation . For example consider the following menmber function of the helper class :

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

So is this is the proper way or should i open the database once like this :

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

if so then where should we close the database ?

Stop! Wait! Freeze!

"I am currently implementing a databasehalper class which will be accessed from various threads so it'll basically be singleton and accessed like this : "

You say your HistoryDatabaseHelper will be accessed from various threads and you forget to synchronize the getInstance method? Your threads are going to wear their running shoes before they leave home since they are definitely up for a race condition. You need to synchronize your getInstance methods if you want your threads to behave like grown ups. Alternately, you can instantiate mInstance instance variable during declaration itself and avoid the need to synchronize getInstance or check whether mInstance has already been initialized inside getInstance.

Next up is the HistoryDatabasrHelper constructor. You need to explicitly declare a private HistoryDatabaseHelper constructor since the compiler will place a public constructor in your class otherwise. Not doing this is like letting your neighbour's steal from you and not handing them over to the cops.

Last but not the least is the Context parameter for the getInstance method. Remove this parameter. Let your HistoryDatabasrHelper have a Context instance variable and initialize it within your private constructor assuming that the Context is not going to change from one instance to another.

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.

This should only be a singleton if HistoryDatabaseHelper is thread-safe. The fact that callers must pass in a parameter to get the singleton should be a big red flag, because it implies that the state of the singleton is related to this parameter.

The safest thing from a threading perspective is to make the class not a singleton, just create a new one as needed. If this turns out to be slowing down your application, then benchmark it and work on a solution, possibly using connection pooling like c3p0, etc.

If you're sure that HistoryDatabaseHelper is thread-safe, then initialize the singleton within the class, and don't require any parameter to get the singleton.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM