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

したがって、パブリックコンストラクターはなく、これがヘルパーにアクセスする唯一の方法です。

今私の質問は、操作を実行しようとするたびにデータベースを開く必要があるということです。たとえば、ヘルパークラスの次の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 パラメーターです。このパラメーターを削除します。HistoryDatabasrHelper に Context インスタンス変数を持たせ、Context がインスタンス間で変更されないと仮定して、プライベート コンストラクター内で初期化します。

では、シングルトン データベース接続が必要ですか? 個人的には、シングルトン データベース接続の代わりにシングルトン データベース接続プールを使用したほうがよいと思います。Google で検索すると、接続プール用の優れたライブラリがたくさん見つかります。

于 2012-10-05T19:34:49.850 に答える
0

HistoryDatabaseHelper がスレッドセーフである場合、これはシングルトンのみにする必要があります。呼び出し元がシングルトンを取得するためにパラメータを渡さなければならないという事実は、シングルトンの状態がこのパラメータに関連していることを意味するため、大きな危険信号である必要があります。

スレッド化の観点から最も安全なのは、クラスをシングルトンではなく、必要に応じて新しいクラスを作成することです。これがアプリケーションの速度を低下させていることが判明した場合は、ベンチマークを行い、おそらく c3p0 などの接続プールを使用して解決策を検討してください。

HistoryDatabaseHelper がスレッドセーフであることが確実な場合は、クラス内でシングルトンを初期化し、シングルトンを取得するためのパラメーターを必要としません。

于 2012-10-05T16:11:29.820 に答える