日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java中数据库连接池_Java中的数据库连接池

發布時間:2025/3/19 java 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中数据库连接池_Java中的数据库连接池 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文譯自Baeldung的博客

概述

連接池是一種眾所周知的數據庫訪問模式,主要目的是減少創建數據庫連接和讀/寫數據庫操作的開銷。

簡單來說,連接池本質上就是數據庫連接緩存的一種實現方式,可以通過對其進行配置來滿足特定的需求。

本文中,我們會簡要介紹一些流行的連接池框架,之后也會討論如何從零開始實現一個連接池。

為何使用連接池

關于這個問題,只要我們分析一下典型的數據庫連接的生命周期中所涉及的步驟,就會明白為什么:

使用數據庫驅動建立一個到數據庫連接;

建立 TCP socket用于讀/寫數據;

通過socket來讀寫數據;

關閉連接;

關閉socket;

很顯然,數據庫連接是非常昂貴的操作,因此在每個可能的應用場景中都要盡量將數據庫連接操作降到最低。

這也就是數據庫連接池發揮作用的地方。

只需要簡單地實現一個數據庫連接容器,使我們可以復用一些已存在的數據庫連接,我們就可以有效地節省大量昂貴的數據庫連接操作消耗的時間成本,從而提高數據庫驅動應用程序的整體性能。

JDBC連接池框架

從實用角度來看,考慮到目前已有很多企業級連接池框架,從頭開始實行連接池是沒有意義的。但是從學習角度,也就是本文的角度來看,并不是無意義的。

即便如此,在開始學習如何實現基本的連接池之前,讓我們首先了解幾個流行的連接池框架。

Apache Commons DBCP

我們首先看一下Apache Commons DBCP組件,這是一個功能齊全的連接池JDBC框架:

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的屬性。使用DBCPDateSource類獲取池化連接的方式如下:

Connection?con?=?DBCPDataSource.getConnection();

復制代碼

C3P0

接著介紹的是C3P0,由Steve Waldman開發,是一個強大的JDBC4連接和語句池框架。

public?class?C3poDataSource{

private?static?ComboPooledDataSource?cpds?=?new?ComboPooledDataSource();

static?{

try?{

cpds.setDriverClass("org.h2.Driver");

cpds.setJdbcUrl("jdbc:h2:mem:test");

cpds.setUser("user");

cpds.setPassword("password");

}?catch?(PropertyVetoException?e)?{

//?handle?the?exception

}

}

public?static?Connection?getConnection()?throws?SQLException{

return?cpds.getConnection();

}

private?C3poDataSource(){}

}

復制代碼

通過C3PoDataSource類獲取池化連接的方式與前面類似:

Connection?con?=?C3poDataSource.getConnection();

復制代碼

HikariCP

最后來看一下HikariCP,一個由Breet Wooldridge開發的快速JDBC連接池框架。我們會在后續的文章中詳細介紹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();

復制代碼

連接池簡單實現

為了更好地理解連接池的底層邏輯,我們來實現一個簡單的連接池。

首先,我們基于單個接口做一個松耦合設計:

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?connectionPool;

private?List?usedConnections?=?new?ArrayList<>();

private?static?int?INITIAL_POOL_SIZE?=?10;

public?static?BasicConnectionPool?create(String?url,

String?user,

String?password)

throws?SQLException{

List?pool?=?new?ArrayList<>(INITIAL_POOL_SIZE);

for?(int?i?=?0;?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

}

復制代碼

雖然很簡單,但BasicConnectionPool類確實提供了我們期望從典型的連接池得到的基礎功能。簡單來說,該類基于一個可存儲10個數據庫連接的ArrayList來初始化連接池,從而使得這些連接可以被復用。

我們可以使用DriverManager類或Datasource實現來創建JDBC連接。從設計的角度來看,屏蔽數據庫連接的創建過程更好,因此我們在create()靜態工廠方法中選擇了前者。

在本例中,我們把創建連接的方法放在了BasicConnectionPool類中,因為這個類是連接池接口的唯一實現類。但是在更復雜的設計中,可能存在多個ConnectionPool實現類,此時最好將該方法放在接口中,從而獲得更靈活的設計和更強的內聚性。

需要強調的一點是,一旦創建了連接池,所有的連接都會從池中獲取,因此不需要創建新的連接。此外,當一個連接被釋放時,它實際上是被歸還到池中,以便其他客戶端可以重用它。

這里與底層數據庫沒有任何進一步的交互,例如對連接的close()方法的顯式調用。

對于BasicConnectionPool的使用非常簡單,我們可以寫一個簡單的單元測試,獲取一個內存數據庫H2的池化連接:

@Test

public?whenCalledgetConnection_thenCorrect(){

ConnectionPool?connectionPool?=?BasicConnectionPool

.create("jdbc:h2:mem:test",?"user",?"password");

assertTrue(connectionPool.getConnection().isValid(1));

}

復制代碼

改進與重構

當然,我們還有很大的空間去改進或者擴展現在的線程池實現。

比如說,我們可以重構getConnection()方法,增加對最大連接池規模參數的支持。如果所有可用的連接都已經被使用,而且當前的連接數小于配置的最大值,該方法會創建新的連接:

@Override

public?Connection?getConnection()?throws?SQLException{

if?(connectionPool.isEmpty())?{

if?(usedConnections.size()?

connectionPool.add(createConnection(url,?user,?password));

}?else?{

throw?new?RuntimeException(

"Maximum?pool?size?reached,?no?available?connections!");

}

}

Connection?connection?=?connectionPool.remove(connectionPool.size()?-?1);

usedConnections.add(connection);

return?connection;

}

復制代碼

需要注意,該方法在這里拋出了SQLException,這意味著我們也需要修改接口中的方法簽名。

此外,我們也可以增加方法來優雅地關閉連接池實例:

public?void?shutdown()?throws?SQLException{

usedConnections.forEach(this::releaseConnection);

for?(Connection?c?:?connectionPool)?{

c.close();

}

connectionPool.clear();

}

復制代碼

在企業級實現中,連接池需要提供很多額外的特性,比如跟蹤當前使用中的連接的能力,對于預編譯語句池的支持,等等。

為了保證簡潔明了,我們省略了這些額外特性的實現,同時提供的也是非線程安全的實現。

在本文中,我們研究了什么是連接池,并學習了如何實現我們自己的連接池。

當然,我們需要在應用程序中添加連接池時,不必從頭開發全新的連接池。這就是為什么我們首先對線程池做了簡單的介紹,并展示了一些流行的連接池框架,以便于我們可以清楚地了解它們的使用方式,并選擇最適合我們要求的框架。

總結

以上是生活随笔為你收集整理的java中数据库连接池_Java中的数据库连接池的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产一区欧美一区 | 性欢交69精品久久久 | 国产十区 | 在线精品视频一区 | 国产成人毛片 | 亚洲精品香蕉 | 涩里番在线观看 | 一区二区韩国 | 国产一二三在线 | 日韩第一页在线 | 操小妹影院 | 黄色成人av | 91自啪 | 97视频久久久 | 日日操夜夜爱 | 日本不卡中文字幕 | www.好了av.com| 98国产视频 | 久操视频网站 | 欧美a图| 久草网在线观看 | 涩涩网址| 久久网国产 | 亚洲黄色免费在线观看 | 伊人网中文字幕 | 久久理论 | 私人影院毛片 | 18av在线播放 | 国产精品91在线 | 色亚洲视频 | 鲁大师私人影院在线观看 | 国产一级不卡毛片 | av美女网站 | 91精品国自产在线偷拍蜜桃 | 福利国产片 | 少妇做爰xxxⅹ性视频 | 日本久久精品 | 七七色影院 | av在线黄色 | 亚洲天堂男人的天堂 | 777午夜| 中文毛片无遮挡高潮免费 | 欧美精品欧美极品欧美激情 | 国产做爰xxxⅹ久久久精华液 | 国产美女永久免费无遮挡 | 山外人精品影院 | 欧美生活一级片 | 欧美丰满美乳xxx高潮www | 欧美狂猛xxxxx乱大交3 | 青青视频免费看 | 国产女主播一区二区三区 | 毛色毛片 | 午夜免费毛片 | 韩国视频一区二区 | 黄色专区| 中文字字幕在线中文 | 无码少妇精品一区二区免费动态 | 久久精品国产网红主播 | 韩国黄色片网站 | 黄色网战入口 | 在线一区不卡 | 国产xxxxwwww| 97人人爽人人爽人人爽 | 欧美少妇15p| 国产视频一二三四区 | 狠狠做深爱婷婷综合一区 | 熟妇人妻系列aⅴ无码专区友真希 | 亚洲精品综合在线 | 亚洲欧美成人综合 | 看全黄大色黄大片美女人 | 成人www| 影音资源av| 国产黄色一级 | 国产黄色影院 | 白浆在线 | 娇妻被老王脔到高潮失禁视频 | 成人性生交大片免费看 | 成人免费a视频 | 天天躁日日躁aaaaxxxx | 淫僧荡尼巨乳(h)小说 | 国产精品一区二区无线 | 中文视频在线 | 秋霞福利网 | 美女黄色在线观看 | 久久久国产精品视频 | 成人精品国产 | 天堂影院一区二区 | 一区二区三区不卡视频 | 国产又粗又猛又爽又黄的视频小说 | 纯爱无遮挡h肉动漫在线播放 | 男人视频网站 | 欧美日韩国产片 | 日批在线观看视频 | 亚洲人成亚洲人成在线观看 | 丁香激情五月少妇 | 成年人午夜影院 | 一本一道精品欧美中文字幕 | 国产一级网站 | 精品一区二区三区无码按摩 |