How to establish a connection pool in JDBC?

前端 未结 13 2292
一个人的身影
一个人的身影 2020-11-22 02:43

Can anybody provide examples or links on how to establish a JDBC connection pool?

From searching google I see many different ways of doing this and it is rather conf

相关标签:
13条回答
  • 2020-11-22 02:48

    HikariCP

    It's modern, it's fast, it's simple. I use it for every new project. I prefer it a lot over C3P0, don't know the other pools too well.

    0 讨论(0)
  • 2020-11-22 02:49

    If you need a standalone connection pool, my preference goes to C3P0 over DBCP (that I've mentioned in this previous answer), I just had too much problems with DBCP under heavy load. Using C3P0 is dead simple. From the documentation:

    ComboPooledDataSource cpds = new ComboPooledDataSource();
    cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
    cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
    cpds.setUser("swaldman");
    cpds.setPassword("test-password");
    
    // the settings below are optional -- c3p0 can work with defaults
    cpds.setMinPoolSize(5);
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(20);
    
    // The DataSource cpds is now a fully configured and usable pooled DataSource 
    

    But if you are running inside an application server, I would recommend to use the built-in connection pool it provides. In that case, you'll need to configure it (refer to the documentation of your application server) and to retrieve a DataSource via JNDI:

    DataSource ds = (DataSource) new InitialContext().lookup("jdbc/myDS");
    
    0 讨论(0)
  • 2020-11-22 02:50

    Usually if you need a connection pool you are writing an application that runs in some managed environment, that is you are running inside an application server. If this is the case be sure to check what connection pooling facilities your application server providesbefore trying any other options.

    The out-of-the box solution will be the best integrated with the rest of the application servers facilities. If however you are not running inside an application server I would recommend the Apache Commons DBCP Component. It is widely used and provides all the basic pooling functionality most applications require.

    0 讨论(0)
  • 2020-11-22 02:52

    You should consider using UCP. Universal Connection Pool (UCP) is a Java connection pool. It is a features rich connection pool and tightly integrated with Oracle's Real Application Clusters (RAC), ADG, DG databases.

    Refer to this page for more details about UCP.

    0 讨论(0)
  • 2020-11-22 02:54

    In the app server we use where I work (Oracle Application Server 10g, as I recall), pooling is handled by the app server. We retrieve a javax.sql.DataSource using a JNDI lookup with a javax.sql.InitialContext.

    it's done something like this

    try {     
       context = new InitialContext();
       jdbcURL = (DataSource) context.lookup("jdbc/CachedDS");
       System.out.println("Obtained Cached Data Source ");
    }
    catch(NamingException e)   
    {  
        System.err.println("Error looking up Data Source from Factory: "+e.getMessage());
    }
    

    (We didn't write this code, it's copied from this documentation.)

    0 讨论(0)
  • 2020-11-22 02:54

    Pool

    • Pooling Mechanism is the way of creating the Objects in advance. When a class is loaded.
    • It improves the application performance [By re using same object's to perform any action on Object-Data] & memory [allocating and de-allocating many objects creates a significant memory management overhead].
    • Object clean-up is not required as we are using same Object, reducing the Garbage collection load.

    « Pooling [ Object pool, String Constant Pool, Thread Pool, Connection pool]

    String Constant pool

    • String literal pool maintains only one copy of each distinct string value. which must be immutable.
    • When the intern method is invoked, it check object availability with same content in pool using equals method. « If String-copy is available in the Pool then returns the reference. « Otherwise, String object is added to the pool and returns the reference.

    Example: String to verify Unique Object from pool.

    public class StringPoolTest {
        public static void main(String[] args) { // Integer.valueOf(), String.equals()
            String eol = System.getProperty("line.separator"); //java7 System.lineSeparator();
    
            String s1 = "Yash".intern();
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s1, s1.hashCode(), System.identityHashCode(s1));
            String s2 = "Yas"+"h".intern();
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s2, s2.hashCode(), System.identityHashCode(s2));
            String s3 = "Yas".intern()+"h".intern();
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s3, s3.hashCode(), System.identityHashCode(s3));
            String s4 = "Yas"+"h";
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s4, s4.hashCode(), System.identityHashCode(s4));
        }
    }
    

    Connection pool using Type-4 Driver using 3rd party libraries[ DBCP2, c3p0, Tomcat JDBC]

    Type 4 - The Thin driver converts JDBC calls directly into the vendor-specific database protocol Ex[Oracle - Thick, MySQL - Quora]. wiki

    In Connection pool mechanism, when the class is loaded it get's the physical JDBC connection objects and provides a wrapped physical connection object to user. PoolableConnection is a wrapper around the actual connection.

    • getConnection() pick one of the free wrapped-connection form the connection objectpool and returns it.
    • close() instead of closing it returns the wrapped-connection back to pool.

    Example: Using ~ DBCP2 Connection Pool with Java 7[try-with-resources]

    public class ConnectionPool {
        static final BasicDataSource ds_dbcp2 = new BasicDataSource();
        static final ComboPooledDataSource ds_c3p0 = new ComboPooledDataSource();
        static final DataSource ds_JDBC = new DataSource();
    
        static Properties prop = new Properties();
        static {
            try {
                prop.load(ConnectionPool.class.getClassLoader().getResourceAsStream("connectionpool.properties"));
    
                ds_dbcp2.setDriverClassName( prop.getProperty("DriverClass") );
                ds_dbcp2.setUrl( prop.getProperty("URL") );
                ds_dbcp2.setUsername( prop.getProperty("UserName") );
                ds_dbcp2.setPassword( prop.getProperty("Password") );
                ds_dbcp2.setInitialSize( 5 );
    
                ds_c3p0.setDriverClass( prop.getProperty("DriverClass") );
                ds_c3p0.setJdbcUrl( prop.getProperty("URL") );
                ds_c3p0.setUser( prop.getProperty("UserName") );
                ds_c3p0.setPassword( prop.getProperty("Password") );
                ds_c3p0.setMinPoolSize(5);
                ds_c3p0.setAcquireIncrement(5);
                ds_c3p0.setMaxPoolSize(20);
    
                PoolProperties pool = new PoolProperties();
                pool.setUrl( prop.getProperty("URL") );
                pool.setDriverClassName( prop.getProperty("DriverClass") );
                pool.setUsername( prop.getProperty("UserName") );
                pool.setPassword( prop.getProperty("Password") );
                pool.setValidationQuery("SELECT 1");// SELECT 1(mysql) select 1 from dual(oracle)
    
                pool.setInitialSize(5);
                pool.setMaxActive(3);
                ds_JDBC.setPoolProperties( pool );
            } catch (IOException e) {   e.printStackTrace();
            } catch (PropertyVetoException e) { e.printStackTrace(); }
        }
    
        public static Connection getDBCP2Connection() throws SQLException {
            return ds_dbcp2.getConnection();
        }
    
        public static Connection getc3p0Connection() throws SQLException {
            return ds_c3p0.getConnection();
        }
    
        public static Connection getJDBCConnection() throws SQLException {
            return ds_JDBC.getConnection();
        }
    }
    public static boolean exists(String UserName, String Password ) throws SQLException {
        boolean exist = false;
        String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";
        try ( Connection connection = ConnectionPool.getDBCP2Connection();
              PreparedStatement pstmt = connection.prepareStatement(SQL_EXIST); ) {
            pstmt.setString(1, UserName );
            pstmt.setString(2, Password );
    
            try (ResultSet resultSet = pstmt.executeQuery()) {
                exist = resultSet.next(); // Note that you should not return a ResultSet here.
            }
        }
        System.out.println("User : "+exist);
        return exist;
    }
    

    jdbc:<DB>:<drivertype>:<HOST>:<TCP/IP PORT>:<dataBaseName> jdbc:oracle:thin:@localhost:1521:myDBName jdbc:mysql://localhost:3306/myDBName

    connectionpool.properties

    URL         : jdbc:mysql://localhost:3306/myDBName
    DriverClass : com.mysql.jdbc.Driver
    UserName    : root
    Password    :
    

    Web Application: To avoid connection problem when all the connection's are closed[MySQL "wait_timeout" default 8 hours] in-order to reopen the connection with underlying DB.

    You can do this to Test Every Connection by setting testOnBorrow = true and validationQuery= "SELECT 1" and donot use autoReconnect for MySQL server as it is deprecated. issue

    ===== ===== context.xml ===== =====
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- The contents of this file will be loaded for a web application -->
    <Context>
        <Resource name="jdbc/MyAppDB" auth="Container" 
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
            type="javax.sql.DataSource" 
    
            initialSize="5" minIdle="5" maxActive="15" maxIdle="10"
    
            testWhileIdle="true"
                timeBetweenEvictionRunsMillis="30000"
    
            testOnBorrow="true"
                validationQuery="SELECT 1"
                validationInterval="30000"
    
    
            driverClassName="com.mysql.jdbc.Driver" 
            url="jdbc:mysql://localhost:3306/myDBName" 
            username="yash" password="777"
        />
    </Context>
    
    ===== ===== web.xml ===== =====
    <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/MyAppDB</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    ===== ===== DBOperations ===== =====
    servlet «   init() {}
    Normal call used by sevlet  « static {}
    
    static DataSource ds;
    static {
        try {
            Context ctx=new InitialContext();
            Context envContext = (Context)ctx.lookup("java:comp/env");
            ds  =   (DataSource) envContext.lookup("jdbc/MyAppDB");
        } catch (NamingException e) {   e.printStackTrace();    }
    }
    

    See these also:

    • am-i-using-jdbc-connection-pooling
    • configuring-jdbc-pool-high-concurrency
    0 讨论(0)
提交回复
热议问题