1。JDBC接続プールとは何ですか?
従来のJDBC接続では、接続接続を取得するたびに、次のコードなど、いくつかの複雑なコードをロードする必要があります。
public static Connection getConn(){connection conn = null; string url = "jdbc:mysql:// localhost:3306/test";文字列ユーザー= "root";文字列パスワード= "root"; try {class.forname( "com.mysql.jdbc.driver"); conn = drivermanager.getConnection(url、user、password); } catch(classNotFoundException e){e.printstacktrace(); } catch(sqlexception e){e.printstacktrace(); } return conn; }このような複雑な操作は、接続を取得するためのみです。もちろん、それをツールクラスにカプセル化してアクセスできます(上記の図は接続の接続をカプセル化します)が、各接続をロードするのはパフォーマンスの無駄ですか?パフォーマンスを最適化するために、接続プールが表示されます。
接続プールが初期化されると、いくつかの接続が作成されます。接続する必要がある場合は、接続プールから既存の接続を取得するだけです。初期化された接続がない場合、接続が再現されます。接続を使用した後、接続は破壊されませんが、後で使用するために接続プールに返されます。 (もちろん、接続プーリングはそれほど単純ではありません。紹介は次のとおりです)
一般的に使用される接続プールには、DBCPとC3P0が含まれます。現在、最も主流のものは、アリババのドルイド接続プールと、Tomcat独自のJNDI接続プールです。
2。シンプルな接続プールをカスタマイズします
カスタム接続プールの分析:
1.2。接続プールであるため、DataSourceインターフェイスを実装し、その中にメソッドを実装する必要があります。私たちの状況に基づいて、私たちはgetConnection()メソッドについてです。
2。いくつかの接続オブジェクトを保存するため、コレクションを使用して保存します。追加および削除の頻繁な操作に基づいて、LinkedListを使用します。
3.接続の破壊は、接続を破壊することではなく、接続を接続プールに戻すことです。
コーディング:
1.クラスMyDataSourceを作成し、DataSourceインターフェイスを実装します
このクラスがロードされた場合、接続を保存するためのコンテナが必要なので、静的プロパティを定義します。
private static list <connection> connectionlist = new LinkedList <>();
2。データベース接続を取得する必要があるため、データベース接続を取得するメソッドをカプセル化します。
public connection getoneconnection(){connection conn = null; {//ここで取得したデータは、より柔軟な外部プロパティファイルを介して取得されます。 inputstream in = mydatasource.class.getClassLoader()。 getResourceasStream( "JDBC/JDBC.Properties"); Properties Pro = new Properties(); pro.load(in); driver = pro.getProperty( "driver"); url = pro.getProperty( "url"); username = pro.getProperty( "user");パスワード= pro.getProperty( "password"); class.forname(ドライバー); conn = drivermanager.getConnection(url、username、password); } catch(Exception E){e.getStackTrace(); } return conn; }プロパティファイルを介して取得したデータは、実際の状況に従って選択できることに注意してください。
3.いくつかの接続を初期化し、コンテナに入れます。静的コードブロックを使用して実装できますが、このデータソースが使用されない場合、リソース廃棄物を引き起こすため、コンストラクターに複数の接続を初期化する実装を検討しました。つまり、この接続プールが必要なときに、それに応じていくつかの接続を作成します。次のように:
public MydataSource(){for(int i = 0; i <5; i ++){connection conn = getoneconnection(); //メソッドを呼び出してconnectionlist.add(conn); }}4.次に、外部メソッドを上書きして、この接続プールから接続を取得するためにgetConnection()を取得します
@Override public connection getConnection()throws sqlexception {connection conn = null; if(connectionlist == null || connectionlist.size()<= 0){connection connection = getConnection(); connectionlist.add(connection); } conn = connectionlist.remove(0); conn; }5.オブジェクトリターンメソッドを作成し、使用済み接続を接続プールに入れます
public void backconnection(connection conn){connectionlist.add(conn); }わかりました、これはシンプルなカスタム接続プールを完成させ、テストコードは次のとおりです。
public static void main(string [] args)throws sqlexception {mydatasource dataSource = new MyDataSource();接続conn = dataSource.getConnection(); string sql = "select * from user where u_id =?"; represedStatement PS = null;結果rs = null; try {ps = conn.preparestatement(sql); ps.setint(1、1); rs = ps.executequery(); while(rs.next()){system.out.println( "id ="+rs.getint(1)); System.out.println( "username ="+rs.getString(2)); System.out.println( "password ="+rs.getString(3)); }} catch(sqlexception e){e.printstacktrace(); }最後に{dataSource.backConnection(conn); }}無視するため、私のコードには他に2つのオブジェクトが閉じることはありません。
これで、接続プール法を介して閉鎖接続が達成されるという小さな問題があります。ただし、ユーザーが接続オブジェクトの緊密な方法を呼び出すと、接続が破壊され、接続プールに返されません。次に、ユーザーが接続を破壊せず、接続を返すように最適化します。
その中には、多くの解決策があり、ここに装飾モデルがあります。
最適化:
1.接続インターフェイスを実装する新しいクラスmyConnectionを作成します。この属性タイプは、接続connとliis <connection>です。
プライベート接続conn;プライベートリスト<Connection>プール; public myConnection(connection conn、list <connection> pool){this.conn = conn; this.pool = pool; }2。次に、インターフェイスの閉じる方法を実装します
@Override public void close()throws sqlexception {system.out.println( "Recycle Connection"); pool.add(conn); }3。次に、ステートメントを取得する方法を実装します。実装されていない場合、このステートメントを取得するときにnullポインターエラーが発生します。準備された測定を取得する方法のみを実装します。
@Override Public PredepredStatement PrepareStatement(String SQL)THROWS SQLEXCEPTION {System.out.Println( "Get Statement"); return conn.preparestatement(SQL); }4.次に、MyDataSourceクラスのメソッドバックコネクションを削除して接続を返し、コンストラクターとメソッドを変更して、次のように接続を取得します
public mydatasource2(){for(int i = 0; i <5; i ++){connection conn = getoneconnection(); myConnection myConn = new myConnection(conn、connectionList); connectionlist.add(myconn); }} @Override public connection getConnection()throws sqlexception {connection conn = null; if(connectionlist == null || connectionlist.size()<= 0){connection connection = getConnection(); myConnection myConn = new myConnection(connection、connectionList); connectionlist.add(myconn); } conn = connectionlist.remove(0); conn; }わかりました。これにより、ユーザーが接続を直接呼び出すことで接続を破壊しないようにし、接続プールに正しく戻します。テストコードを少し変更してテストできます。
上記の記事は、私があなたと共有したコンテンツ全体です。私はそれがあなたに参照を与えることができることを願っています、そしてあなたがwulin.comをもっとサポートできることを願っています。