JDBC中如何建立连接池?

发布于 2024-09-01 17:30:01 字数 246 浏览 5 评论 0 原文

任何人都可以提供有关如何建立 JDBC 连接池的示例或链接吗?

通过搜索谷歌,我看到了许多不同的方法来做到这一点,这相当令人困惑。

最终我需要代码来返回 java.sql.Connection 对象,但我在入门时遇到了困难......欢迎任何建议。

更新:javax.sqljava.sql 没有池化连接实现吗?为什么不最好使用这些呢?

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 confusing.

Ultimately I need the code to return a java.sql.Connection object, but I am having trouble getting started..any suggestions welcome.

Update: Doesn't javax.sql or java.sql have pooled connection implementations? Why wouldn't it be best to use these?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

-小熊_ 2024-09-08 17:30:02

如果您需要独立的连接池,我优先选择 C3P0 而不是 DBCP (我在此 上一个答案),我在重负载下的 DBCP 遇到了太多问题。使用 C3P0 非常简单。来自 文档

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 

但是如果您在应用程序服务器内运行,我建议使用它提供的内置连接池。在这种情况下,您需要配置它(请参阅应用程序服务器的文档)并通过 JNDI 检索数据源:

DataSource ds = (DataSource) new InitialContext().lookup("jdbc/myDS");

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");
撩心不撩汉 2024-09-08 17:30:02

HikariCP

它现代、快速、简单。我将它用于每个新项目。
与 C3P0 相比,我更喜欢它,不太了解其他池。

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.

浅暮の光 2024-09-08 17:30:02

通常,如果您需要连接池,那么您正在编写在某些托管环境中运行的应用程序,即在应用程序服务器内运行。如果是这种情况,请务必检查连接池是什么在尝试任何其他选项之前,应用程序服务器提供的设施

开箱即用的解决方案将与其他应用程序服务器设施最好地集成。但是,如果您没有在应用程序服务器内运行,我会推荐 Apache Commons DBCP 组件< /强>。它被广泛使用并提供大多数应用程序所需的所有基本池功能。

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.

亚希 2024-09-08 17:30:02

不要重新发明轮子。

尝试使用现成的第 3 方组件之一:

Apache DBCP 附带了有关如何设置池的不同示例 javax.sql.DataSource。这是一个可以帮助您入门的示例

Don't reinvent the wheel.

Try one of the readily available 3rd party components:

  • Apache DBCP - This one is
    used internally by Tomcat, and by
    yours truly.
  • c3p0

Apache DBCP comes with different example on how to setup a pooling javax.sql.DataSource. Here is one sample that can help you get started.

吃→可爱长大的 2024-09-08 17:30:02

我建议使用 commons-dbcp 库。这里列出了许多关于如何使用它的示例是移动的链接简单的< /a>.使用方法非常简单:

 BasicDataSource ds = new BasicDataSource();
 ds.setDriverClassName("oracle.jdbc.driver.OracleDriver")
 ds.setUsername("scott");
 ds.setPassword("tiger");
 ds.setUrl(connectURI);
 ...
 Connection conn = ds.getConnection();

您只需要创建一次数据源,因此如果您不知道如何执行此操作,请务必阅读文档。如果您不知道如何正确编写 JDBC 语句以免泄漏资源,您可能还需要阅读此 维基百科页面。

I would recommend using the commons-dbcp library. There are numerous examples listed on how to use it, here is the link to the move simple one. The usage is very simple:

 BasicDataSource ds = new BasicDataSource();
 ds.setDriverClassName("oracle.jdbc.driver.OracleDriver")
 ds.setUsername("scott");
 ds.setPassword("tiger");
 ds.setUrl(connectURI);
 ...
 Connection conn = ds.getConnection();

You only need to create the data source once, so make sure you read the documentation if you do not know how to do that. If you are not aware of how to properly write JDBC statements so you do not leak resources, you also might want to read this Wikipedia page.

隔纱相望 2024-09-08 17:30:02

在我工作的地方使用的应用程序服务器(我记得是 Oracle 应用服务器 10g)中,池由应用程序服务器处理。我们检索 javax.sql.DataSource 使用带有 < 的 JNDI 查找代码>javax.sql.InitialContext

它做了类似的事情

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

(我们没有编写这段代码,它是从 本文档。)

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.)

早乙女 2024-09-08 17:30:02

2017 年底,Proxool、BoneCP、C3P0、DBCP 此时大多已不复存在。 HikariCP(创建于 2012 年)看起来很有前途,超越了我所知道的任何其他产品。
http://www.baeldung.com/hikaricp

Proxool 有许多问题:
- 在重负载下可能会超过最大连接数并且不会返回低于最大连接数
- 即使在连接过期后也可以设法不返回到最小连接
- 如果在 HouseKeeper 线程期间连接到数据库时遇到问题,可以锁定整个池(以及所有服务器/客户端线程)(不使用 .setQueryTimeout)
- HouseKeeper 线程在其进程具有连接池锁定的同时,请求 Prototyper 线程重新创建连接(清除),这可能会导致竞争条件/锁定。在这些方法调用中,最后一个参数在循环期间应始终为 swing:false,只有在其下方的 swing:true。
- HouseKeeper 最后只需要单个 PrototypeController 扫描,并且还有更多[上面提到的]
- HouseKeeper 线程在查看哪些连接可能过期之前检查连接测试[测试过期连接的一些风险,这些连接可能会因防火墙等数据库中的其他超时而被破坏/终止]
- 项目有未完成的代码(已定义但未执行的属性)
- 如果未定义,默认最大连接寿命为 4 小时(过多)
- 每个池的 HouseKeeper 线程每五秒运行一次(过多)

您可以修改代码并进行这些改进。但由于它创建于 2003 年,并于 2008 年更新,因此缺乏 hikaricp 等解决方案所利用的近 10 年的 java 改进。

In late 2017 Proxool, BoneCP, C3P0, DBCP are mostly defunct at this time. HikariCP (created in 2012) seems promising, blows the doors off anything else I know of.
http://www.baeldung.com/hikaricp

Proxool has a number of issues:
- Under heavy load can exceed max number of connections and not return below max
- Can manage to not return to min connections even after connections expire
- Can lock up the entire pool (and all server/client threads) if it has trouble connecting to the database during HouseKeeper thread (does not use .setQueryTimeout)
- HouseKeeper thread, while having connection pool lock for its process, requests the Prototyper thread to recreate connections (sweep) which can result in race condition/lockup. In these method calls the last parameter should always be sweep:false during the loop, only sweep:true below it.
- HouseKeeper only needs the single PrototypeController sweep at the end and has more [mentioned above]
- HouseKeeper thread checks for testing of connections before seeing what connections may be expired [some risk of testing expired connection that may be broken/terminated through other timeouts to DB in firewall, etc.]
- The project has unfinished code (properties that are defined but not acted upon)
- The Default max connection life if not defined is 4 hours (excessive)
- HouseKeeper thread runs every five seconds per pool (excessive)

You can modify the code and make these improvements. But as it was created in 2003, and updated in 2008, its lacking nearly 10 years of java improvements that solutions like hikaricp utilize.

永言不败 2024-09-08 17:30:02

Pool

  • 池化机制是预先创建对象的方式。当一个类被加载时。
  • 它提高了应用程序性能 [通过重新使用相同的对象对对象数据执行任何操作] & 内存 [分配和取消分配许多对象会产生大量的内存管理开销]。
  • 由于我们使用相同的对象,因此不需要对象清理,从而减少了垃圾收集负载。

« 池 [ 对象 池,字符串常量池,线程池、连接池]

<字符串常量池

  • 字符串文字池仅维护每个不同字符串值的一份副本。这必须是不可变的。
  • 当调用 intern 方法时,它使用 equals 方法检查池中具有相同内容的对象可用性。
    « 如果字符串复制在池中可用,则返回引用。
    « 否则,String 对象将被添加到池中并返回引用。

示例:要验证的字符串 唯一对象< /a> 来自池。

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

使用 Type-4 驱动程序的连接池 使用第 3 方库[ DBCP2c3p0, Tomcat JDBC]

类型 4 - Thin 驱动程序将 JDBC 调用直接转换为供应商特定的数据库协议 Ex[Oracle - Thick、MySQL - Quora]。 wiki

在连接池机制中,当加载类时,它会得到 物理 JDBC 连接 对象,并向用户提供包装的物理连接对象。 PoolableConnection 是实际连接的包装器。

  • getConnection() 从连接中选择一个免费的包装连接objectpool 并返回它。
  • close() 不是关闭,而是将包装的连接返回到池中。

示例:在 Java 7 中使用 ~ DBCP2 连接池[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:::::
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 应用程序:为了避免所有连接都关闭时出现连接问题[MySQL“wait_timeout”默认 8 小时],以便重新打开与底层数据库的连接。

您可以通过设置 testOnBorrow = true 和validationQuery= "SELECT 1" 来测试每个连接,并且不要将 autoReconnect 用于 MySQL 服务器它已被弃用。 问题< /em>

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

另请参阅:

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:

A君 2024-09-08 17:30:02

正如其他人的回答,您可能会对 Apache Dbcpc3p0。两者都很受欢迎,而且效果都很好。

关于您的疑问

javax.sql 或 java.sql 没有
池连接实现?为什么
使用这些不是最好吗?

它们不提供实现,而是提供接口和一些支持类,仅与实现第三方库(池或驱动程序)的程序员相关。通常你甚至不会看它。您的代码应该以透明的方式处理池中的连接,就像它们是“普通”连接一样。

As answered by others, you will probably be happy with Apache Dbcp or c3p0. Both are popular, and work fine.

Regarding your doubt

Doesn't javax.sql or java.sql have
pooled connection implementations? Why
wouldn't it be best to use these?

They don't provide implementations, rather interfaces and some support classes, only revelant to the programmers that implement third party libraries (pools or drivers). Normally you don't even look at that. Your code should deal with the connections from your pool just as they were "plain" connections, in a transparent way.

半世蒼涼 2024-09-08 17:30:02

Vibur DBCP 是另一个用于此目的的库。可以在其网站上找到几个示例,展示如何配置它以与 Hibernate、Spring+Hibernate 或以编程方式一起使用:http ://www.vibur.org/

另外,请参阅此处的免责声明。

Vibur DBCP is another library for that purpose. Several examples showing how to configure it for use with Hibernate, Spring+Hibernate, or programatically, can be found on its website: http://www.vibur.org/

Also, see the disclaimer here.

心房敞 2024-09-08 17:30:02

Apache Commons 有一个用于此目的的库:DBCP。除非您对池有奇怪的要求,否则我会使用库,因为它肯定比您希望的更棘手和更微妙。

Apache Commons has a library for that purpose: DBCP. Unless you have strange requirements around your pools, I'd use a library as it's bound to be trickier and more subtle than you would hope.

沙沙粒小 2024-09-08 17:30:02

您应该考虑使用 UCP。
通用连接池(UCP)是一个Java连接池。它是一个功能丰富的连接池,并与 Oracle 的真正应用集群 (RAC)、ADG、DG 数据库紧密集成。

有关 UCP 的更多详细信息,请参阅此页面

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.

极致的悲 2024-09-08 17:30:02

MiniConnectionPoolManager 是一个单 java 文件实现,如果您'正在寻找可嵌入的解决方案,并且不太关心性能(尽管我还没有在这方面进行过测试)。

它是多重许可的EPLLGPLMPL

它的文档还提供了值得检查的替代方案(在 DBCP 和 C3P0 之上):

MiniConnectionPoolManager is a one-java-file implementation, if you're looking for an embeddable solution and are not too concerned about performances (though I haven't tested it in that regard).

It is multi-licensed EPL, LGPL and MPL.

Its documentation also gives alternatives worth checking (on top of DBCP and C3P0):

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文