簡體   English   中英

實現單例SqliteDatabaseHelper類的正確方法

[英]Proper way of implementing a singleton SqliteDatabaseHelper class

我當前正在實現一個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;
                   }

如果是這樣,那我們應該在哪里關閉數據庫?

停止! 等待! 凍結!

“我目前正在實現一個databasehalper類,該類可以從各個線程進行訪問,因此它基本上將是單例的,並且可以這樣訪問:”

您說您的HistoryDatabaseHelper將通過各種線程進行訪問,而您忘記了同步getInstance方法? 您的線程在離開家之前要穿上跑鞋,因為它們肯定適合比賽條件。 如果您希望線程的行為像大人一樣,則需要同步getInstance方法。 或者,您可以在聲明本身期間實例化mInstance實例變量,而無需同步getInstance或檢查getInstance內部是否已初始化mInstance。

接下來是HistoryDatabasrHelper構造函數。 您需要顯式聲明一個私有的HistoryDatabaseHelper構造函數,因為否則編譯器會將公共構造函數放置在您的類中。 不這樣做,就像是讓鄰居的竊賊從您手中竊取,而不是將其移交給警察。

最后但並非最不重要的是getInstance方法的Context參數。 刪除此參數。 讓您的HistoryDatabasrHelper具有一個Context實例變量,並在您的私有構造函數中對其進行初始化,假設Context不會從一個實例更改為另一個實例。

那你應該有一個單例數據庫連接嗎? 我個人認為,如果您有一個單例數據庫連接池而不是一個單例數據庫連接,那將是一個更好的主意。 Google搜索將為您提供許多很好的庫,用於在那里進行連接池。

如果HistoryDatabaseHelper是線程安全的,則只能是單例。 調用者必須傳遞參數以獲取單例的事實應該是一個大的危險信號,因為這意味着單例的狀態與此參數有關。

從線程的角度來看,最安全的事情是使該類不是單例,只需根據需要創建一個新類。 如果事實證明這使您的應用程序變慢,請對其進行基准測試並開發解決方案,可能使用諸如c3p0等的連接池。

如果確定HistoryDatabaseHelper是線程安全的,則在類中初始化單例,並且不需要任何參數即可獲取單例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM