【问题标题】:Connection pool in java which allows to get connection by jdbc url?java中的连接池允许通过jdbc url获取连接?
【发布时间】:2019-09-17 07:38:42
【问题描述】:

我试图找到允许通过 jdbc url 获取连接的连接池,但失败了。 Hikari 连接池不允许这样做,c3po 中的情况相同。 我的用例是:

ConnectionPool.getConnection(jdbcUrl);

有人知道java世界中这样的连接池吗?

【问题讨论】:

  • 我怀疑它的存在,因为它们每个都是DataSource,而DataSource 不满足这一点,我怀疑实现它的池会。
  • 你能不能用文档引用 github.com/brettwooldridge/HikariCP987654321@
  • 你能详细说明你想要做什么吗? “通过 JDBC url 获取连接”是什么意思?它是如何失败的?也许您的网址不正确?因为 Hikari 允许基于 url 的连接 a.k.a “DriverManager-based”
  • @Amongalen 我更新了问题。就我而言,我应该能够连接到不同的数据库。在 Hikary 中我找到了 setJdbcUrl 方法,但我不明白这个方法之后会发生什么。我找不到这种方法的文档。另一种情况是,我希望能够更改 jdbc 驱动程序的类加载器。
  • 为什么不使用多个DataSources?每个数据库一个。这也将允许您基于数据库调整池。你并不真正需要你所要求的,所以这可能是没有人费心去实现它的原因之一。

标签: java jdbc connection-pool


【解决方案1】:

A Simple Guide to Connection Pooling in Java

作者 - Baeldung

About Author

一个简单的实现

为了更好地理解连接池的底层逻辑,让我们 创建一个简单的实现。

让我们从松耦合设计开始,仅基于一个 单界面:

public interface ConnectionPool {
    Connection getConnection();
    boolean releaseConnection(Connection connection);
    String getUrl();
    String getUser();
    String getPassword();
}

ConnectionPool 接口定义了一个基本的公共 API 连接池。

现在,让我们创建一个实现,它提供了一些基本的 功能,包括获取和释放池连接:

public class BasicConnectionPool 
  implements ConnectionPool {

    private String url;
    private String user;
    private String password;
    private List<Connection> connectionPool;
    private List<Connection> usedConnections = new ArrayList<>();
    private static int INITIAL_POOL_SIZE = 10;

    public static BasicConnectionPool create(
      String url, String user, 
      String password) throws SQLException {

        List<Connection> pool = new ArrayList<>(INITIAL_POOL_SIZE);
        for (int i = 0; i < INITIAL_POOL_SIZE; i++) {
            pool.add(createConnection(url, user, password));
        }
        return new BasicConnectionPool(url, user, password, pool);
    }

    // standard constructors

    @Override
    public Connection getConnection() {
        Connection connection = connectionPool
          .remove(connectionPool.size() - 1);
        usedConnections.add(connection);
        return connection;
    }

    @Override
    public boolean releaseConnection(Connection connection) {
        connectionPool.add(connection);
        return usedConnections.remove(connection);
    }

    private static Connection createConnection(
      String url, String user, String password) 
      throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    public int getSize() {
        return connectionPool.size() + usedConnections.size();
    }

    // standard getters
}

连接池是一种众所周知的数据访问模式,其主要 目的是减少执行数据库所涉及的开销 连接和读/写数据库操作。

简而言之,连接池在最基本的层面上是一个 数据库连接缓存实现,可配置为 满足特定要求。

在本教程中,我们将快速总结一些流行的 连接池框架,我们将学习如何实现 划伤我们自己的连接池。

为什么要使用连接池?

当然,这个问题是修辞性的。

如果我们分析典型数据库中涉及的步骤顺序 连接生命周期,我们会明白为什么:

使用数据库驱动程序打开到数据库的连接 用于读取/写入数据的 TCP 套接字 socket 关闭连接 关闭socket 很明显 数据库连接是相当昂贵的操作,并且作为 这样,应该在每个可能的用例中减少到最低限度(在 边缘情况,只是避免)。

这就是连接池实现发挥作用的地方。

只需简单地实现一个数据库连接容器,它 允许我们重用一些现有的连接,我们可以 有效节省大量昂贵的执行成本 数据库旅行,从而提高了我们的整体性能 数据库驱动的应用程序。

JDBC 连接池框架

从务实的角度来看,从 考虑到数量,地面只是毫无意义 “企业就绪”的连接池框架可用。

从一个说教的角度来看,这是本文的目标,它不是。

即便如此,在我们学习如何实现一个基本的连接池之前, 让我们先展示几个流行的连接池框架。

Apache Commons DBCP

public class DBCPDataSource {

    private static BasicDataSource ds = new BasicDataSource();

    static {
        ds.setUrl("jdbc:h2:mem:test");
        ds.setUsername("user");
        ds.setPassword("password");
        ds.setMinIdle(5);
        ds.setMaxIdle(10);
        ds.setMaxOpenPreparedStatements(100);
    }

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

    private DBCPDataSource(){ }
}

在这种情况下,我们使用了一个带有静态块的包装类来轻松地 配置 DBCP 的属性。

以下是使用 DBCPDataSource 类获取池连接的方法:

connection con = DBCPDataSource.getConnection();

HikariCP

public class HikariCPDataSource {

    private static HikariConfig config = new HikariConfig();
    private static HikariDataSource ds;

    static {
        config.setJdbcUrl("jdbc:h2:mem:test");
        config.setUsername("user");
        config.setPassword("password");
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        ds = new HikariDataSource(config);
    }

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

    private HikariCPDataSource(){}
}

同样,以下是如何与 HikariCPDataSource 类:

Connection con = HikariCPDataSource.getConnection();

【讨论】:

  • @user207421 你能告诉我吗,我听不懂,我会满足你的要求,谢谢你更新我
  • @user207421 我改了一些东西,请你看看,如果有问题,我会重新修改它
猜你喜欢
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 2016-07-06
  • 2011-03-06
  • 2018-09-10
  • 1970-01-01
  • 2012-05-09
相关资源
最近更新 更多