mysql api 连接池_SpringBoot-整合HikariCP连接池
HikariCP連接池概述池化思想
池化思想是我們項目開發過程中的一種非常重要的思想,如整數池,字符串池,對象池、連接池、線程池等都是池化思想的一種應用,都是 通過復用對象,以減少因創建和釋放對象所帶來的資源消耗,進而來提升系統性能。 例如Integer對象的內部池應用。
package com.cy.java.pool;
public class TestInteger01 {
public static void main(String[] args) {
Integer n1=100;//Integer.valueOf(100) 編譯時優化
Integer n2=100;
Integer n3=200;
Integer n4=200;//池中沒有則new Integer(200)
System.out.println(n1==n2);//true
System.out.println(n3==n4);//false
}
}
這就是因為Intrger對象維護了一個常量池,相同數據不再開辟空間存儲區間是-128--127。連接池原理
在系統初始化的時候,在內存中開辟一片空間,將一定數量的數據庫連接作為對象存儲在對象池里,并對外提供數據庫連接的獲取和歸還方法。用戶訪問數據庫時,并不是建立一個新的連接,而是從數據庫連接池中取出一個已有的空閑連接對象;使用完畢歸還后的連接也不會馬上關閉,而是由數據庫連接池統一管理回收,為下一次借用做好準備。如果由于高并發請求導致數據庫連接池中的連接被借用完畢,其他線程就會等待,直到有連接被歸還。整個過程中,連接并不會關閉,而是源源不斷地循環使用,有借有還。數據庫連接池還可以通過設置其參數來控制連接池中的初始連接數、連接的上下限數,以及每個連接的最大使用次數、最大空閑時間等,也可以通過其自身的管理機制來監視數據庫連接的數量、使用情況等。java中的連接池
Java官方,為了在應用程序中更好的應用連接池技術,定義了一套數據源規范,例如javax.sql.DataSource接口,基于這個接口,很多團隊或個人創建了不同的連接池對象。然后我們的應用程序中通過耦合與DataSource接口,便可以方便的切換不同廠商的連接池。Java項目中通過連接池獲取連接的一個基本過程,如下圖所示:
在上圖中,用戶通過DataSource對象的getConnection()方法,獲取一個連接。假如池中有連接,則直接將連接返回給用戶。假如池中沒有連接,則會調用Dirver(驅動,由數據庫廠商進行實現)對象的connect方法從數據庫獲取,拿到連接以后,可以將連接在池中放一份,然后將連接返回給調用方。連接需求方再次需要連接時,可以從池中獲取,用完以后再還給池對象。
數據庫連接池在Java數據庫相關中間件產品群中,應該算是底層最基礎的一類產品,作為企業應用開發必不可少的組件,無數天才們為我們貢獻了一個又一個的優秀產品,它們有的隨時代發展,功成身退,有的則還在不斷迭代,老而彌堅,更有新生代產品,或性能無敵,或功能全面。目前市場上常見的連接池有DBCP、C3P0,DRUID,HikariCP等。SpringBoot工程下HikariCP整合測試數據初始化
打開mysql控制臺,然后按如下步驟執行goods.sql文件。
第一步:登錄mysql。
mysql –uroot –p1234
第二步:設置控制臺編碼方式。
set names utf8;
第三步:執行goods.sql文件(切記不要打開文件復制到mysql客戶端運行)。
source d:/goods.sql
其中goods.sql文件內容如下:
drop database if exists dbgoods;
create database dbgoods default character set utf8;
use dbgoods;
create table tb_goods(
id bigint primary key auto_increment,
name varchar(100) not null,
remark text,
createdTime datetime not null
)engine=InnoDB;
insert into tb_goods values (null,'java','very good',now());
insert into tb_goods values (null,'mysql','RDBMS',now());
insert into tb_goods values (null,'Oracle','RDBMS',now());
insert into tb_goods values (null,'java','very good',now());
insert into tb_goods values (null,'mysql','RDBMS',now());
insert into tb_goods values (null,'Oracle','RDBMS',now());
insert into tb_goods values (null,'java','very good',now()); 創建項目Module并添加相關依賴
第一步:基于IDEA創建項目Module,如圖所示:
SpringBoot-整合HikariCP連接池
第二步:添加依賴
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> 配置HikariCP連接池
打開application.properties配置文件,添加如下內容(必寫)。
#spring datasource
spring.datasource.url=jdbc:mysql:///dbgoodsserverTimezone=GMT%2B8&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=1234
hikariCP 其它額外配置(可選),代碼如下(具體配置不清晰的可自行百度):
spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.connection-test-query=SELECT 1 HikariCP 連接池測試
單元測試API設計及應用分析,如圖所示:
在項目中添加單元測試類及測試方法,代碼如下:
package com.cy.pj.common.datasource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.sql.DataSource;
@SpringBootTest public class DataSourceTests {
/**
* DataSource 由誰定義? java 官方
* DataSource 定義了什么? 定義了從數據庫或連接池獲取連接Connection的一種規范
* 我們為什么要耦合于它? 類與之間存在依賴(耦合)時,盡量依賴于抽象規范。
* 程序運行時這個變量指向的對象類型是誰?HikariDataSource 你是怎么知道的?
*/ @Autowired
private DataSource dataSource; //interface
@Test
public void testConnection() throws Exception{
//通過datasource獲取連接的一個過程是怎么樣的 System.out.println(dataSource.getConnection()); //HikariProxyConnection@524566446 wrapping com.mysql.cj.jdbc.ConnectionImpl@73ba6fe6
}
}
在當前測試類中我們需要:
- 掌握單元測試類、測試方法編寫規范。
- 理解DataSource的設計規范及規范的實現。
- 分析在測試類中dataSource屬性指向的對象是誰?
- 分析在測試類中DataSource的實現類對象由誰創建和管理?
- 思考基于DataSource接口獲取連接的基本過程是怎樣的?
基于HikariCP實現JDBC操作業務分析
基于HikariCP,借助JDBC技術訪問商品庫中的數據。API架構設計
基于業務,進行API設計,如圖所示:
業務時序圖分析
基于業務需求,進行商品查詢過程的的時序圖設計,如圖所示:
業務代碼設計及實現
第一步:定義GoodsDao接口,例如:
package com.cy.pj.goods.dao;
import java.util.List;
import java.util.Map;
/**
* 商品模塊數據訪問層接口
*/
public interface GoodsDao {
/**
* 查詢所有商品信息,將每一行記錄存儲到一個map對象,然后將多個存儲到list集合.
*/ List<Map<String,Object>> findGoods();
}
第二步:創建GoodsDao接口實現類,代碼如下:
package com.cy.pj.goods.dao;
/**
* 此對象為一個商品數據層訪問對象,現在要求在此類中定義一個方法,這個方法基于JDBC從從數據庫獲取商品信息,并將其封裝到map集合,要求一個行記錄一個map對象(key為表中字段名,值為字段名對應的值),多個map存儲到list集合. @Repository此注解通常用于描述數據層實現類對象,本質上就是一個特殊的@Component, 都是要交給spring框架管理的一個Bean對象 */
@Repository
public class DefaultGoodsDao implements GoodsDao{
@Autowired private DataSource dataSource;//hikariCP
/**查詢商品信息,一行記錄映射為內存中的一個map對象*/
public List<Map<String,Object>> findGoods(){
Connection conn=null;//java.sql.*
Statement stmt=null;
ResultSet rs=null;
String sql="select * from tb_goods";
//1.獲取連接(從連接池獲取)
try {
conn=dataSource.getConnection();
//2.創建statement對象
stmt=conn.createStatement();
//3.發送sql
rs=stmt.executeQuery(sql);
//4.處理結果
List<Map<String,Object>> list=new ArrayList<>();
while(rs.next()){//循環一次取一行,一行記錄映射為一個map對象
list.add( rowMap(rs));//將存儲了一行記錄的map對象再存儲到list集合
}
return list; }catch (SQLException e){
e.printStackTrace();
throw new RuntimeException(e);//轉換為非檢查異常(編譯時不檢測的異常)
}finally{
//5. 釋放資源
close(rs,stmt,conn);
}
}
定義行映射方法
private Map<String,Object> rowMap(ResultSet rs)throws SQLException{
Map<String,Object> rowMap=new HashMap<>();
//方法1映射
//rowMap.put("id",rs.getInt("id"));
//rowMap.put("name",rs.getString("name")); //rowMap.put("remark",rs.getString("remark")); //rowMap.put("createdTime",rs.getTimestamp("createdTime"));
//方法2映射
ResultSetMetaData rsmd=rs.getMetaData();//獲取元數據(包括表中的字段名)
int columnCount=rsmd.getColumnCount();//獲取列的數量
for(int i=0;i<columnCount;i++){ rowMap.put(rsmd.getColumnLabel(i+1),rs.getObject(rsmd.getColumnLabel(i+1)));
//getColumnLabel(i+1);獲取表中字段名或字段名對應的別名
}
return rowMap;
}
定義釋放資源的方法
private void close(ResultSet rs,Statement stmt,Connection conn){ if(rs!=null)try{rs.close();}catch(Exception e){e.printStackTrace();} if(stmt!=null)try{stmt.close();}catch(Exception e){e.printStackTrace();} //這里的連接是返回到了池中
if(conn!=null)try{conn.close();}catch(Exception e){e.printStackTrace();}
}
} 測試代碼的編寫及運行
定義單元測試類,并對其查詢過程進行單元測試,例如:
package com.cy.pj.goods.dao;
@SpringBootTest
public class GoodsDaoTests {
@Autowired
private GoodsDao goodsDao;
@Test
void testFindGoods(){
List<Map<String,Object>> list= goodsDao.findGoods();
for(Map<String,Object> map:list){
System.out.println(map);
}
}
} 測試運行過程中的BUG分析
對測試過程中出現的問題進行記錄,分析,總結.總結(Summary)
總之,數據庫連接池的為我們的項目開發及運行帶來了很多優點,具體如下:
- 資源重用更佳。
由于數據庫連接得到復用,減少了大量創建和關閉連接帶來的開銷,也大大減少了內存碎片和數據庫臨時進程、線程的數量,使得整體系統的運行更加平穩。
- 系統調優更簡便。
使用了數據庫連接池以后,由于資源重用,大大減少了頻繁關閉連接的開銷,大大降低了TIME_WAIT的出現頻率。
- 系統響應更快。
數據庫連接池在應用初始化的過程中一般都會提前準備好一些數據庫連接,業務請求可以直接使用已經創建的連接,而不需要等待創建連接的開銷。初始化數據庫連接配合資源重用,使得數據庫連接池可以大大縮短系統整體響應時間。
- 連接管理更靈活。
數據庫連接池作為一款中間件,用戶可以自行配置連接的最小數量、最大數量、最大空閑時間、獲取連接超時間、心跳檢測等。另外,用戶也可以結合新的技術趨勢,增加數據庫連接池的動態配置、監控、故障演習等一系列實用的功能。
總結
以上是生活随笔為你收集整理的mysql api 连接池_SpringBoot-整合HikariCP连接池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java绘制图形代码_ImagePy_L
- 下一篇: node获取服务器cpu信息,听说你不知