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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

14-数据库连接池和jdbc优化

發布時間:2024/9/27 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 14-数据库连接池和jdbc优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、數據庫連接池

1. 什么是連接池

傳統的開發模式下,Servlet處理用戶的請求,找Dao查詢數據,dao會創建與數據庫之間的連接,完成數據查詢后會關閉數據庫的鏈接。

這樣的方式會導致用戶每次請求都要向數據庫建立鏈接而數據庫創建連接通常需要消耗相對較大的資源,創建時間也較長。假設網站一天10萬訪問量,數據庫服務器就需要創建10萬次連接,極大的浪費數據庫的資源,并且極易造成數據庫服務器內存溢出、宕機。

?

解決方案就是數據庫連接池

連接池就是數據庫連接對象的一個緩沖池

我們可以先創建10個數據庫連接緩存在連接池中,當用戶有請求過來的時候,dao不必創建數據庫連接,而是從數據庫連接池中獲取一個,用完了也不必關閉連接,而是將連接換回池子當中,繼續緩存

?

使用數據庫連接池可以極大地提高系統的性能

?

2. 實現數據庫連接池

jdbc統一了數據庫的操作? 定義了規范

jdbc針對數據庫連接池也定義的接口java.sql.DataSource,所有的數據庫連接池實現都要實現該接口

該接口中定義了兩個重載的方法

Connection getConnection()

Connection getConnection(String?username, String?password)

?

數據庫連接池實現思路

1) 定義一個類實現java.sql.DataSource接口

2) 定義一個集合用于保存Connection對象,由于頻繁地增刪操作,用LinkedList比較好

3) 實現getConnection方法,在方法中取出LinkedList集合中的一個連接對象返回

注意:

??? 返回的Connection對象不是從集合中獲得,而是刪除

??? 用戶用完Connection,會調用close方法釋放資源,此時要保證連接換回連接池,而不是關閉連接

??? 重寫close方法是難點,解決方案: 裝飾設計模式、動態代理

?

二、 數據源

通常我們把DataSource的實現,按其英文含義稱之為數據源,數據源中都包含了數據庫連接池的實現。

?

一些開源組織提供了數據源的獨立實現,常用的有:

DBCP 數據庫連接池

C3P0 數據庫連接池

1.? DBCP 數據源

介紹

DBCP 是 Apache 軟件基金組織下的開源連接池實現

tomcat服務器就是使用DBCP作為數據庫連接池

使用DBCP數據源,需要導入兩個jar包

Commons-dbcp.jar:連接池的實現

Commons-pool.jar:連接池實現的依賴庫

?

DBCP核心 API

BasicDataSource

數據源實現

BasicDataSourceFactory

用于創建數據源的工廠類

?

dbcp 創建連接池

方法1:? 直接創建對象,設置參數

BasicDataSource bds = new BasicDataSource();

?

// 設置連接數據庫需要的配置信息

bds.setDriverClassName("com.mysql.jdbc.Driver");

bds.setUrl("jdbc:mysql://localhost:3306/jdbc3");

bds.setUsername("root");

bds.setPassword("root");

?

// 設置連接池的參數

bds.setInitialSize(5);

bds.setMaxActive(10);

?

ds = bds

?

方法2: 通過工廠類創建對象,讀取配置文件

try {

?? Properties prop = new Properties();

?? // 讀配置文件

?? InputStream in =

?? ?? JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");

?? prop.load(in);

?? ds = BasicDataSourceFactory.createDataSource(prop);

}catch (Exception e) {

?? throw new ExceptionInInitializerError(e);

}

?

配置文件為dbcpconfig.properties

#連接設置

driverClassName=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/jdbc3

username=root

password=root

?

#<!-- 初始化連接 -->

initialSize=5

?

#最大連接數量

maxActive=10

?

#<!-- 最大空閑連接 -->

maxIdle=10

?

?

#<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等于60 -->

maxWait=60000

?

?

#JDBC驅動建立連接時附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;]

#注意:"user" "password" 兩個屬性會被明確地傳遞,因此這里不需要包含他們。

connectionProperties=useUnicode=true;characterEncoding=gbk

?

#指定由連接池所創建的連接的自動提交(auto-commit)狀態。

defaultAutoCommit=true

?

#driver default 指定由連接池所創建的連接的只讀(read-only)狀態。

#如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動并不支持只讀模式,如:Informix

defaultReadOnly=

?

#driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。

#可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE

defaultTransactionIsolation=READ_UNCOMMITTED

2.? C3P0 數據源

介紹

c3p0是一個開源的jdbc連接池,我們熟悉的 Hibernate和 Sprint 框架使用的都是該數據源

?

創建連接池對象

方法1:直接創建對象,設置參數

ComboPooledDataSource cpds = new ComboPooledDataSource();

cpds.setDriverClass("com.mysql.jdbc.Driver");

cpds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc3");

cpds.setUser("root");

cpds.setPassword("root");

cpds.setInitialPoolSize(5);

cpds.setMaxPoolSize(15);

方法2:讀取配置文件

ComboPooledDataSource cpds = new ComboPooledDataSource("itcast");

配置文件為c3p0-config.xml 該文件需要放在類路徑下

<c3p0-config>

?

?? <default-config>

?? ?? <!—- 默認配置 –->

????? <property name="initialPoolSize">5</property>

????? <property name="maxPoolSize">15</property>

????? <property name="driverClass">com.mysql.jdbc.Driver</property>

????? <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc3</property>

????? <property name="user">root</property>

????? <property name="password">root</property>

?? </default-config>

?? <named-config name="xwh">

????? <property name="initialPoolSize">5</property>

????? <property name="maxPoolSize">15</property>

????? <property name="driverClass">com.mysql.jdbc.Driver</property>

????? <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc3</property>

????? <property name="user">root</property>

????? <property name="password">root</property>

?? </named-config>

</c3p0-config>

?

三、ResultSetMetaData對象

元數據,可以理解為描述數據的數據

jdbc中的元數據是指數據庫、表、列的定義信息

?

ResultSetMetaData對象表示結果集 ResultSet對象的元數據

獲得該對象:

ResultSetMetaData metaData = rs.getMetaData();

?

常用方法:

getColumnCount() ?返回resultset對象的列數

getColumnName(int?column) ?獲得指定列的名稱

getColumnTypeName(int?column) 獲得指定列的類型

?

四、jdbc優化

使用jdbc對數據庫進行crud操作時,會有很多重復的代碼,仔細分析不難發現其實變化的只是其中幾行代碼

?

對于 cud(增刪改) 操作,代碼幾乎完全一樣, 唯一的區別就是sql語句不同,我們完全可以把相同的代碼抽取出來定義在一個工具方法中,然后定義一個參數來接收sql語句

?

對于 r(查詢) 操作,除SQL語句不同之外,根據操作的實體不同,對ResultSet結果集的處理也有所不相同,因此可義一個query方法,除以參數形式接收變化的SQL語句外,可以使用策略模式由qurey方法的調用者決定如何把ResultSet中的數據映射到實體對象中

?

優化后的工具類 JdbcUtils

// 通用的增刪改方法

publicstaticint update(String sql, Object[] params) throws SQLException {

?? Connection conn = null;

?? PreparedStatement pstmt = null;

?? ResultSet rs = null;

?? try {

????? // 獲得連接

????? conn = getConnection();

????? // 預編譯sql

????? pstmt = conn.prepareStatement(sql);

????? // 將參數設置進去

????? for(int i=0;? params!=null&&i<params.length; i++) {

???????? pstmt.setObject(i+1, params[i]);

????? }

????? // 發送sql

????? int num = pstmt.executeUpdate();

????? return num;

?? } finally {

????? // 釋放資源

????? release(conn, pstmt, rs);

?? }

}

?

// 優化查詢

publicstatic Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException {

?? Connection conn = null;

?? PreparedStatement pstmt = null;

?? ResultSet rs = null;

?? try {

????? // 獲得連接

????? conn = getConnection();

????? // 預編譯sql

????? pstmt = conn.prepareStatement(sql);

????? // 將參數設置進去

????? for(int i=0; params!=null&&i<params.length; i++) {

???????? pstmt.setObject(i+1, params[i]);

????? }

????? // 發送sql

????? rs = pstmt.executeQuery();

????? // 不知道別人想如何處理結果集

????? // 干脆想別人所要一個結果集的處理器

????? // 為了讓當前代碼繼續,定義一個結果集處理器接口

????? // 策略模式,規定算法,具體的算法留給將來的調用者實現

????? Object obj = rsh.handle(rs);

????? return obj;

?? } finally {

????? // 釋放資源

????? release(conn, pstmt, rs);

?? }

}

?

?

結果集處理器接口

public interface ResultSetHandler {

?? // 處理結果集的方法

?? public Object handle(ResultSet rs);

}

?

實現類:

BeanListHandler

public class BeanListHandler implements ResultSetHandler {

?

?? private Class clazz;

?? public BeanListHandler(Class clazz) {

????? this.clazz = clazz;

?? }

?? public Object handle(ResultSet rs) {

????? try {

???????? // 取出結果集所有的記錄,封裝到bean,存入list返回

???????? List list = new ArrayList();

???????? while (rs.next()) {

??????????? Object bean = clazz.newInstance();

??????????? // 獲得元數據

??????????? ResultSetMetaData metaData = rs.getMetaData();

??????????? // 獲得列的數量

??????????? int count = metaData.getColumnCount();

??????????? // 遍歷列

??????????? for(int i=1; i<=count; i++) {

??????????????? // 取列名

??????????????? String columnName = metaData.getColumnName(i);

??????????????? // 取這列的值

??????????????? Object value = rs.getObject(columnName);

??????????????? // 反射出屬性

??????????????? Field field = clazz.getDeclaredField(columnName);

??????????????? // 設置屬性

??????????????? field.setAccessible(true);

??????????????? field.set(bean, value);

??????????? }

??????????? // 加入list

??????????? list.add(bean);

???????? }

???????? return list;

????? } catch (Exception e) {

???????? throw new RuntimeException(e);

????? }

?? }

?

}

?

BeanHandler

public class BeanHandler implements ResultSetHandler {

?? private Class clazz;

?? public BeanHandler(Class clazz) {

????? this.clazz = clazz;

?? }

?? public Object handle(ResultSet rs) {

????? // 不知道有幾列數據,不知道列名,不知道封裝到什么樣的bean

????? // 表的列明和javabean的字段名一致

????? try {

???????? if(rs.next()) {

??????????? // 創建bean

??????????? Object bean = clazz.newInstance();

??????????? // 封裝數據

??????????? // 獲得結果集的元數據

??????????? ResultSetMetaData metaData = rs.getMetaData();

??????????? int count = metaData.getColumnCount();

??????????? // 迭代取每一列的數據

??????????? for(int i=1; i<=count; i++) {

??????????????? // 獲得列名? username

??????????????? String columnName = metaData.getColumnName(i);

??????????????? // 獲得數據 ddd

??????????????? Object value = rs.getObject(columnName);

??????????????? // 根據列名反射出映射的屬性 username

??????????????? Field field = clazz.getDeclaredField(columnName);

??????????????? // 為屬性賦值

??????????????? field.setAccessible(true);

??????????????? field.set(bean, value);

??????????? }

??????????? return bean;

???????? }

???????? return null;

????? } catch (Exception e) {

???????? throw new RuntimeException(e);

????? }

?? }

?

}

?

ArrayHandler

// 取出第一行的所有記錄存入一個Object數組

public class ArrayHandler implements ResultSetHandler {

?

?? public Object handle(ResultSet rs) {

????? try {

???????? if (rs.next()) {

??????????? // 指向了第一行的記錄

??????????? // 獲得元數據

??????????? ResultSetMetaData metaData = rs.getMetaData();

??????????? // 獲得列數

??????????? int count = metaData.getColumnCount();

??????????? // 創建數組

??????????? Object[] arr = new Object[count];

??????????? // 迭代所有列的值,存入數組

??????????? for(int i=1; i<=count; i++) {

??????????????? Object value = rs.getObject(i);?? // 獲得指定列的值

??????????????? arr[i-1] = value;

??????????? }

??????????? return arr;

???????? }

???????? return null;

????? } catch (Exception e) {

???????? throw new RuntimeException(e);

????? }

?? }

?

}

?

批處理

?

處理大數據

Clob Character large Object

text

?

Blob binary? large object

?

?

?

?

?

總結

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

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

主站蜘蛛池模板: av成人天堂 | 久久黄色片视频 | 亚洲激情视频在线观看 | 亚洲高清天堂 | 亚洲黄色在线观看视频 | 国产日韩欧美一区 | 日韩精品一区二区三区不卡 | 国精产品一品二品国精品69xx | 看av的网址| 草碰在线视频 | 精品视频在线观看免费 | 韩国美女一区 | 日本高清视频一区 | 伊人色影院 | 丁香婷婷激情五月 | 日韩美女三级 | 成人h动漫精品一区二区 | 美女啪啪免费视频 | 亚洲视频在线看 | 黄网站免费在线 | 美女四肢被绑在床扒衣 | 国产亚洲精品美女久久久 | 亚洲日本japanese丝袜 | 亚瑟av在线 | 色多多黄色 | 爱爱精品视频 | 欧美又粗又长又爽做受 | 免费中文字幕在线观看 | 欧美日韩极品 | caoporn成人| 成人黄色激情视频 | 91日日夜夜 | 在线观看黄色小视频 | 成年人免费在线 | 波多野结衣亚洲天堂 | 国产欧美一区二区三区国产幕精品 | 欧美国产日韩综合 | 欧美日韩人妻精品一区 | 岛国精品一区二区 | 久久精品视频8 | www网站在线观看 | 国产又粗又猛又色 | 夜夜噜噜噜 | 国产精品视频一区二区三区 | 第一章豪妇荡乳黄淑珍 | 久久久久久激情 | 亚洲国产网 | 男女互操视频 | 91久久久久久久久久 | 国产探花一区 | 中文国产在线观看 | 国产欧美一区二区 | 污黄网站在线观看 | 久久高清一区 | 男女黄床上色视频 | 青草青青视频 | 99国产超薄肉色丝袜交足 | 国产精品爽爽久久久久久 | 日皮在线观看 | 国产毛片99 | 古装做爰无遮挡三级聊斋艳谭 | 国产情侣免费视频 | 国产精品自产拍高潮在线观看 | 性色AV无码久久一区二区三 | 天堂中文视频在线 | 成人视频在线观看 | jzzjzz日本丰满成熟少妇 | 色吧av| 国产精品h| 亚洲一区电影在线观看 | 日日干夜夜艹 | 青青草国产成人av片免费 | 免费a视频在线观看 | 国产情侣在线播放 | 国产免费看片 | 久久久久中文字幕亚洲精品 | 日韩城人视频 | 99精品久久久久久久 | 国产一级特黄 | 国产高清精品在线 | 密臀av| 99福利视频 | 人妻熟人中文字幕一区二区 | 中文字幕成人av | jizzz18 | 天天操天天摸天天干 | www天堂在线 | 亚洲精品国产精品乱码不卡 | 久久久久久久久久国产精品 | 日韩一区免费观看 | 少妇熟女一区 | 亚洲最黄视频 | 国产成人愉拍精品久久 | 久久亚洲av无码西西人体 | 男女羞羞无遮挡 | 亚洲精品99| av成人精品 | 亚洲逼逼| 亚欧精品视频一区二区三区 |