Sto usando il pool di connessioni JDBC?

Sto cercando di determinare se sto effettivamente usando il pool di connessioni JDBC. Dopo aver fatto qualche ricerca, l’implementazione sembra quasi troppo facile. Più facile di una connessione regolare, quindi mi piacerebbe verificare.

Ecco la mia class di connessione:

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

}

Questo vero pool di connessioni? Sto usando la connessione in un’altra class in questo modo:

  //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("
"); } 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); }

Supponendo che sia BasicDataSource sia da DBCP , allora sì, stai usando un pool di connessioni. Tuttavia, stai ricreando un altro pool di connessioni su ogni acquisizione di connessione. Non stai realmente collegando le connessioni dalla stessa piscina. È necessario creare il pool di connessioni solo una volta all’avvio dell’applicazione e ottenere ogni connessione da esso. Non dovresti tenere la connessione come variabile di istanza. Dovresti anche chiudere la connessione, l’istruzione e il set di risultati per assicurarti che le risorse siano correttamente chiuse, anche in caso di eccezioni. In questo è utile l’ istruzione try-with-resources Java 7, che chiuderà automaticamente le risorse quando il blocco try è terminato.

Ecco una riscrittura minore:

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

(questo può, se necessario, essere rifattorizzato come una fabbrica astratta per migliorare la connettività)

e

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

che deve essere usato come segue:

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

In un ambiente Java EE reale, è necessario debind la creazione di DataSource al server contenitore / applicazione e ottenerlo da JNDI. Nel caso di Tomcat, vedere anche questo documento: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html

Non sembra che sia messo insieme. È necessario memorizzare DataSource in DatabaseConnection invece di crearne uno nuovo con ciascuna chiamata getConnection (). getConnection () dovrebbe restituire datasource.getConnection ().

Sembra un utilizzo DBCP. Se è così, allora si. È già in pool. E qui è il valore predefinito della proprietà del pool del DBCP.

 /** * 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; 

Di seguito alla soluzione di BalusC, di seguito è una implementazione che posso essere utilizzata all’interno di un’applicazione che richiede più di una connessione, o in una libreria comune che non conoscerebbe le proprietà di connessione in anticipo …

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