2011-09-29 23 views
22

私は実際にJDBC接続プーリングを使用しているかどうかを判断しようとしています。いくつかの調査をした後、実装はほとんど簡単すぎるようです。実際には定期的な接続より簡単なので、私は確認したいと思います。ここで私はJDBC接続プーリングを使用していますか?

は私の接続クラスです:

public class DatabaseConnection { 

Connection conn = null; 

public Connection getConnection() { 

    BasicDataSource bds = new BasicDataSource(); 
    bds.setDriverClassName("com.mysql.jdbc.Driver"); 
    bds.setUrl("jdbc:mysql://localhost:3306/data"); 
    bds.setUsername("USERNAME"); 
    bds.setPassword("PASSWORD"); 

    try{ 
     System.out.println("Attempting Database Connection"); 
     conn = bds.getConnection(); 
     System.out.println("Connected Successfully"); 
    }catch(SQLException e){ 
     System.out.println("Caught SQL Exception: " + e); 
    } 
    return conn; 
} 

public void closeConnection() throws SQLException { 
    conn.close(); 
} 

}

は、この真の接続プーリングですか?私はそう別のクラスでの接続を使用しています:

 //Check data against database. 
    DatabaseConnection dbConn = new DatabaseConnection(); 
    Connection conn; 
    ResultSet rs; 
    PreparedStatement prepStmt; 

    //Query database and check username/pass against table. 
    try{ 
     conn = dbConn.getConnection(); 
     String sql = "SELECT * FROM users WHERE username=? AND password=?"; 
     prepStmt = conn.prepareStatement(sql); 
     prepStmt.setString(1, user.getUsername()); 
     prepStmt.setString(2, user.getPassword()); 
     rs = prepStmt.executeQuery(); 

     if(rs.next()){ //Found Match. 
      do{ 
       out.println("UserName = " + rs.getObject("username") + " Password = " + rs.getObject("password")); 
       out.println("<br>"); 
      } while(rs.next()); 
     } else { 
      out.println("Sorry, you are not in my database."); //No Match. 
     } 

     dbConn.closeConnection(); //Close db connection. 

    }catch(SQLException e){ 
     System.out.println("Caught SQL Exception: " + e); 
    } 

答えて

45

はそれがBasicDataSourceは[はい、あなたは接続プールを使用している、DBCPからであるだと仮定すると。ただし、すべての接続獲得時に別の接続プールを再作成しています。あなたは実際に同じプールからの接続をプールしていません。アプリケーションの起動時に一度だけ接続プールを作成し、そこからすべての接続を取得する必要があります。また、接続をインスタンス変数として保持しないでください。また、接続、文、および結果セットを閉じて、例外の場合でもリソースが適切に閉じられるようにする必要があります。 Java 7のtry-with-resources statementはこの点で役立ち、tryブロックが終了するとリソースを自動クローズします。

public final class Database { 

    private static final BasicDataSource dataSource = new BasicDataSource(); 

    static { 
     dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
     dataSource.setUrl("jdbc:mysql://localhost:3306/data"); 
     dataSource.setUsername("USERNAME"); 
     dataSource.setPassword("PASSWORD"); 
    } 

    private Database() { 
     // 
    } 

    public static Connection getConnection() throws SQLException { 
     return dataSource.getConnection(); 
    } 

} 

(これはプラグイン可能性を改善するために、抽象工場として、必要な場合をリファクタリングすることができます)

private static final String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?"; 

public boolean exist(User user) throws SQLException { 
    boolean exist = false; 

    try (
     Connection connection = Database.getConnection(); 
     PreparedStatement statement = connection.prepareStatement(SQL_EXIST); 
    ) { 
     statement.setString(1, user.getUsername()); 
     statement.setString(2, user.getPassword()); 

     try (ResultSet resultSet = preparedStatement.executeQuery()) { 
      exist = resultSet.next(); 
     } 
    }  

    return exist; 
} 

使用されるべきである:ここでは

はマイナー書き換えです次のようになります。

try { 
    if (!userDAO.exist(username, password)) { 
     request.setAttribute("message", "Unknown login. Try again."); 
     request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); 
    } else { 
     request.getSession().setAttribute("user", username); 
     response.sendRedirect("userhome"); 
    } 
} catch (SQLException e) { 
    throw new ServletException("DB error", e); 
} 

実際のJava EE環境では、DataSourceの作成をコンテナ/アプリケーションサーバーに委任し、JNDIから取得する必要があります。 Tomcatの場合、このドキュメントの例も参照してください。http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html

+0

うわー、書き直してくれてありがとう。私のような誰かのための完全な助け。 – ryandlf

+0

このソリューションはスレッドセーフなのでしょうか?私はconnection.close()を呼び出す必要がありますか? – swapyonubuntu

+0

@swapyonubuntu:新しいJava7の「try-with-resources」ステートメントでcloseが自動的に実行されるhttps://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – BalusC

3

プールされていないようです。各getConnection()呼び出しで新しいデータソースを作成するのではなく、DataSourceをDatabaseConnectionに格納する必要があります。 getConnection()はdatasource.getConnection()を返します。

2

DBCPの使用に似ています。そうなら、はい。既にプールされています。次に、DBCPのデフォルトのプールプロパティ値を示します。以下、BalusCのソリューションへのフォローアップとして

/** 
* The default cap on the number of "sleeping" instances in the pool. 
* @see #getMaxIdle 
* @see #setMaxIdle 
*/ 
public static final int DEFAULT_MAX_IDLE = 8; 
/** 
* The default minimum number of "sleeping" instances in the pool 
* before before the evictor thread (if active) spawns new objects. 
* @see #getMinIdle 
* @see #setMinIdle 
*/ 
public static final int DEFAULT_MIN_IDLE = 0; 
/** 
* The default cap on the total number of active instances from the pool. 
* @see #getMaxActive 
*/ 
public static final int DEFAULT_MAX_ACTIVE = 8; 
1

は、私は複数の接続を必要とするアプリケーション内、または事前に接続プロパティを知っているだろう共通ライブラリで使用可能な実装です。..

import org.apache.commons.dbcp.BasicDataSource; 

import java.sql.Connection; 
import java.sql.SQLException; 
import java.util.concurrent.ConcurrentHashMap; 

public final class Database { 

    private static final ConcurrentHashMap<String, BasicDataSource> dataSources = new ConcurrentHashMap(); 

    private Database() { 
     // 
    } 

    public static Connection getConnection(String connectionString, String username, String password) throws SQLException { 

     BasicDataSource dataSource; 

     if (dataSources.containsKey(connectionString)) { 
      dataSource = dataSources.get(connectionString); 
     } else { 
      dataSource = new BasicDataSource(); 
      dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
      dataSource.setUrl(connectionString); 
      dataSource.setUsername(username); 
      dataSource.setPassword(password); 
      dataSources.put(connectionString, dataSource); 
     } 

     return dataSource.getConnection(); 

    } 

} 
+0

この解決法は常に機能しません。 ConcurrentHashMapを使用しているにもかかわらず、競合状態になる可能性があります。 –

関連する問題