2016-09-23 4 views
4

ローカルのH2データベースをJavaFXアプリケーション(Java8)に統合しながら、静的およびシングルトンを回避しようとしています。他の5つのクラス(コントローラを含む)はデータベースへのアクセスを必要とするので、それらの間の1つのH2接続を共有しようとしています。私はConnection Poolを読んで、不要な再接続を避けますが、ここに該当するのであれば混乱します。デスクトップ使用、シングルユーザー。クラス間のH2接続にアクセスする

以下のExtrasDBクラスには、initializeDB,getDBValuesおよびperformQueryの3つのメソッドがあります。以前はこれらのメソッドはstaticでしたので、私はExtrasDB.getDBValues()を使って他のクラスから呼び出すことにしましたが、私のアプリケーションはの複数のスレッドを使用していますので、私はより良いアプローチを探しています。私はすべての静的/シングルトンの使用を私のアプリから取り除く過程にあります。

initializeDBメソッドは、接続を作成し、必要に応じてテーブルを作成します。このメソッドは、メインコントローラのinitializeメソッドから1回だけ呼び出されます。これにより、接続connがそのインスタンスに分離され、ヌルの結果セットをもたらすgetDBValuesまたはperformQueryの他のクラスの呼び出しからアクセスできなくなります。上記のメソッドを使用して、これらのクラスがデータベースに自由にアクセスできるように、データベース接続をすべての必要なクラスにアクセスできるようにするにはどうすればよいですか?

public class ExtrasDB { 

    final String JDBC_DRIVER = "org.h2.Driver"; 
    final String DB_URL = "jdbc:h2:~/mainDB"; 
    final String USER = "test"; 
    final String PASS = "test"; 
    Connection conn = null; 
    Statement statement = null; 
    String myStatement; 
    ResultSet rs; 
    DatabaseMetaData meta; 

    public void initializeDB() { 

     try { 
      Class.forName("org.h2.Driver"); 
      conn = DriverManager.getConnection(DB_URL, USER, PASS); 
      System.out.println("Connected to database successfully..."); 
      statement = conn.createStatement(); 
      meta = conn.getMetaData(); 
      rs = meta.getTables(null, null, "EXTRAS", new String[]{"TABLE"}); // <--- Checks for existence of table "EXTRAS" 

      if (!rs.next()) { 

       System.out.println("Table doesn't exist yet... Creating..."); 
       sql = "CREATE TABLE EXTRAS " + 
         "(column_1 VARCHAR(255), " + 
         " column_2 VARCHAR(255))"; 

       statement.executeUpdate(sql); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 


    public void getDBValues() throws SQLException { 
     rs = statement.executeQuery("SELECT * FROM EXTRAS"); 
     while (rs.next()) { 
      //..... do something 
     } 
    } 

    public void performQuery(String query) { 
     try { 
      statement.executeUpdate(query); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 
+0

'org.h2.test.jdbcx.TestConnectionPool'は例です。 – trashgod

+0

'performQuery(...){executeUpdate(...); } 'うーん...何?データベースを照会すると更新されますか?たぶん 'ResultSet performQuery(){return this.conn.executeQuery(...); } 'あなたは実際に接続を共有して結果を得る必要はありませんか? –

+0

@trashgod、私は理解したかった* [その例](https://github.com/pkouki/recsys2015/blob/master/h2/src/test/org/h2/test/jdbcx/TestConnectionPool.java) *、 'testKeepOpen()'メソッドは 'man.dispose()'だけがプールを閉じる方法を示しているようですが、私は混乱しています:(1)クラス 'ExtrasDB'を' public static ... ' 'public'や' private'の3つのメソッドはどうでしょうか?私が尋ねる理由は、(2)私の他のクラスはどちらもExtrasDbを使うことができます。getDBValues() '(静的)ですが、代わりに各クラスにExtrasDBオブジェクトを作成すると、新しいConnectionPoolが作成されます。 1つを共有する方法? – MM88

答えて

0

静的アクセスのいくつかの並べ替えをしたくない場合は、2つのオプションがあります。

  1. は、あなたのプログラムの起動時に(静的でない)サービス・ファクトリーインスタンスを作成します。 Service-Factoryは、他のクラス間で共有したいすべての依存関係を含むpojoクラスです。これらの依存関係は、Service-Factoryによって作成されたり、セッターで設定されたりする可能性があります。依存関係を必要とするすべてのクラスは、Factoryインスタンスを提供するだけです。
  2. 自動依存性注入を実装するフレームワークを使用できます。このようなフレームワークでは、コンストラクタまたはフィールドに注釈を付けるだけで済みます。依存性注入の詳細についてはthis linkを参照し、依存性注入にはSpringフレームワークの使用方法についてはthis tutorialを参照してください。

私のJavaFX-Appでは、最初のオプションを使用しています。 Rootという名前のクラスがあり、javafx.application.Application :: start関数内にそのインスタンスを作成します。いくつかの依存関係はRootクラスによって作成され、いくつかの依存関係(たとえばコントローラインスタンス)はsetterを使用して設定されます。私はFXMLローダー経由で私のコントローラを搭載していますので、私は、ルート・インスタンスを提供するために、コンストラクタを使用しカントが、あなたはより多くの助けが必要な場合は代わりに、すべてのコントローラは、init関数

public void initialize(Root root); 

を持っています。この回答をコメントしてください。

関連する問題