數(shù)據(jù)庫(kù)常用連接池總結(jié)

數(shù)據(jù)庫(kù)常用連接池總結(jié)

一、為什么需要連接池

發(fā)展壯大離不開(kāi)廣大客戶長(zhǎng)期以來(lái)的信賴與支持,我們將始終秉承“誠(chéng)信為本、服務(wù)至上”的服務(wù)理念,堅(jiān)持“二合一”的優(yōu)良服務(wù)模式,真誠(chéng)服務(wù)每家企業(yè),認(rèn)真做好每個(gè)細(xì)節(jié),不斷完善自我,成就企業(yè),實(shí)現(xiàn)共贏。行業(yè)涉及垃圾桶等,在成都網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站、WAP手機(jī)網(wǎng)站、VI設(shè)計(jì)、軟件開(kāi)發(fā)等項(xiàng)目上具有豐富的設(shè)計(jì)經(jīng)驗(yàn)。

數(shù)據(jù)庫(kù)連接是一種關(guān)鍵的有限的昂貴的資源,這一點(diǎn)在多用戶的網(wǎng)頁(yè)應(yīng)用程序中體現(xiàn)得尤為突出。? 一個(gè)數(shù)據(jù)庫(kù)連接對(duì)象均對(duì)應(yīng)一個(gè)物理數(shù)據(jù)庫(kù)連接,每次操作都打開(kāi)一個(gè)物理連接,使用完都關(guān)閉連接,這樣造成系統(tǒng)的 性能低下。
數(shù)據(jù)庫(kù)連接池的解決方案是在應(yīng)用程序啟動(dòng)時(shí)建立足夠的數(shù)據(jù)庫(kù)連接,并講這些連接組成一個(gè)連接池,由應(yīng)用程序動(dòng)態(tài)地對(duì)池中的連接進(jìn)行申請(qǐng)、使用和釋放。
對(duì)于多于連接池中連接數(shù)的并發(fā)請(qǐng)求,應(yīng)該在請(qǐng)求隊(duì)列中排隊(duì)等待。并且應(yīng)用程序可以根據(jù)池中連接的使用率,動(dòng)態(tài)增加或減少池中的連接數(shù)。
?連接池技術(shù)盡可能多地重用了消耗內(nèi)存地資源,大大節(jié)省了內(nèi)存,提高了服務(wù)器地服務(wù)效率,能夠支持更多的客戶服務(wù)。通過(guò)使用連接池,將大大提高程序運(yùn)行效率,同時(shí),我們可以通過(guò)其自身的管理機(jī)制來(lái)監(jiān)視數(shù)據(jù)庫(kù)連接的數(shù)量、使用情況等。


二、定義

數(shù)據(jù)庫(kù)連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫(kù)連接,它允許應(yīng)用程序重復(fù)使用一個(gè)現(xiàn)有的數(shù)據(jù)庫(kù)連接,而不是再重新建立一個(gè)。


三、工作原理

連接池的工作原理主要由三部分組成,分別為連接池的建立、連接池中連接的使用管理、連接池的關(guān)閉。
第一、連接池的建立。一般在系統(tǒng)初始化時(shí),連接池會(huì)根據(jù)系統(tǒng)配置建立,并在池中創(chuàng)建了幾個(gè)連接對(duì)象,以便使用時(shí)能從連接池中獲取。連接池中的連接不能隨意創(chuàng)建和關(guān)閉,這樣避免了連接隨意建立和關(guān)閉造成的系統(tǒng)開(kāi)銷。Java中提供了很多容器類可以方便的構(gòu)建連接池,例如Vector、Stack等。
第二、連接池的管理。連接池管理策略是連接池機(jī)制的核心,連接池內(nèi)連接的分配和釋放對(duì)系統(tǒng)的性能有很大的影響。其管理策略是: 當(dāng)客戶請(qǐng)求數(shù)據(jù)庫(kù)連接時(shí),首先查看連接池中是否有空閑連接,如果存在空閑連接,則將連接分配給客戶使用;如果沒(méi)有空閑連接,則查看當(dāng)前所開(kāi)的連接數(shù)是否已經(jīng)達(dá)到最大連接數(shù),如果沒(méi)達(dá)到就重新創(chuàng)建一個(gè)連接給請(qǐng)求的客戶;如果達(dá)到就按設(shè)定的最大等待時(shí)間進(jìn)行等待,如果超出最大等待時(shí)間,則拋出異常給客戶。
當(dāng)客戶釋放數(shù)據(jù)庫(kù)連接時(shí),先判斷該連接的引用次數(shù)是否超過(guò)了規(guī)定值,如果超過(guò)就從連接池中刪除該連接,否則保留為其他客戶服務(wù)。
該策略保證了數(shù)據(jù)庫(kù)連接的有效復(fù)用,避免頻繁的建立、釋放連接所帶來(lái)的系統(tǒng)資源開(kāi)銷。
?第三、連接池的關(guān)閉。當(dāng)應(yīng)用程序退出時(shí),關(guān)閉連接池中所有的連接,釋放連接池相關(guān)的資源,該過(guò)程正好與創(chuàng)建相反。


四、傳統(tǒng)數(shù)據(jù)庫(kù)連接對(duì)比數(shù)據(jù)庫(kù)連接池

數(shù)據(jù)庫(kù)常用連接池總結(jié)

不使用數(shù)據(jù)庫(kù)連接池的步驟:
TCP建立連接的三次握手
MySQL認(rèn)證的三次握手
真正的SQL執(zhí)行
MySQL的關(guān)閉
TCP的四次握手關(guān)閉
可以看到,為了執(zhí)行一條SQL,卻多了非常多我們不關(guān)心的網(wǎng)絡(luò)交互。

優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單
缺點(diǎn):

  1. 網(wǎng)絡(luò)IO較多
  2. 數(shù)據(jù)庫(kù)的負(fù)載較高
  3. 響應(yīng)時(shí)間較長(zhǎng)及QPS較低
  4. 應(yīng)用頻繁的創(chuàng)建連接和關(guān)閉連接,導(dǎo)致臨時(shí)對(duì)象較多,GC頻繁
  5. 在關(guān)閉連接后,會(huì)出現(xiàn)大量TIME_WAIT 的TCP狀態(tài)(在2個(gè)MSL之后關(guān)閉)

數(shù)據(jù)庫(kù)常用連接池總結(jié)

使用數(shù)據(jù)庫(kù)連接池的步驟:

第一次訪問(wèn)的時(shí)候,需要建立連接。 但是之后的訪問(wèn),均會(huì)復(fù)用之前創(chuàng)建的連接,直接執(zhí)行SQL語(yǔ)句。

優(yōu)點(diǎn):

較少了網(wǎng)絡(luò)開(kāi)銷
系統(tǒng)的性能會(huì)有一個(gè)實(shí)質(zhì)的提升
沒(méi)了麻煩的TIME_WAIT狀態(tài)


五、常用連接池對(duì)比
目前存在多個(gè)開(kāi)源的java數(shù)據(jù)庫(kù)連接池,這些連接池都是在java.sql基礎(chǔ)上編寫而成。

建數(shù)據(jù)庫(kù)test,然后在創(chuàng)建表

CREATE TABLE `user` (
  `userid` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(255) DEFAULT NULL,
  `password` VARCHAR(255) DEFAULT NULL,
  `email` VARCHAR(255) DEFAULT NULL,
  `phone` VARCHAR(255) DEFAULT NULL,
  `status` VARCHAR(255) NOT NULL DEFAULT '0',
  `code` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=INNODB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;

DBCP連接池
DBCP 是 Apache 軟件基金組織下的開(kāi)源連接池實(shí)現(xiàn),使用DBCP數(shù)據(jù)源,應(yīng)用程序應(yīng)在系統(tǒng)中增加如下兩個(gè) jar 文件:
Commons-dbcp.jar:連接池的實(shí)現(xiàn)
Commons-pool.jar:連接池實(shí)現(xiàn)的依賴庫(kù)
Tomcat 的連接池正是采用該連接池來(lái)實(shí)現(xiàn)的。該數(shù)據(jù)庫(kù)連接池既可以與應(yīng)用服務(wù)器整合使用,也可由應(yīng)用程序獨(dú)立使用。
核心類:org.apache.commons.dbcp2.BasicDataSourceextends Object implements DataSource

數(shù)據(jù)庫(kù)常用連接池總結(jié)

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory;
import org.junit.Test;

import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class SqlDriverManage {
    private final String driverClassName = "com.mysql.cj.jdbc.Driver";
    private final String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";
    private final String userName = "root";
    private final String userPassword = "123456";
    Connection con=null;
    PreparedStatement pst=null;
    ResultSet rs=null;
    /*
     * 使用java.sql.DriverManager類----傳統(tǒng)方式,沒(méi)有使用連接池,需要引入mysql驅(qū)動(dòng)包
     */
    @Test
    public void test1(){
        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            Class.forName(driverClassName);
            //2.獲取連接對(duì)象
            con= DriverManager.getConnection(url,userName, userPassword);
            //3.準(zhǔn)備sql
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //7.關(guān)閉連接(順序:后打開(kāi)的先關(guān)閉)
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(pst!=null){
                try {
                    pst.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(con!=null){
                try {
                    con.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    }
/*
     * 第一種方式使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類--DBCP連接池硬編碼
     * 在上述代碼中添加單元測(cè)試代碼
     */  
    @Test
    public void test2(){

        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            BasicDataSource bds=new BasicDataSource();
            bds.setDriverClassName(driverClassName);
            bds.setUrl(url);
            bds.setUsername(userName);
            bds.setPassword(userPassword);
            //2.獲取連接對(duì)象
            con=bds.getConnection();
            //3.準(zhǔn)備sql語(yǔ)句
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
/*
     *第二種方式使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類--DBCP連接池軟編碼
     */
    @Test
    public void test3(){
        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            Properties pro=new Properties();
            BasicDataSource bds=null;
            InputStream inStream=SqlDriverManage.class.getResourceAsStream("dbcp.properties");
            pro.load(inStream);
            bds=new BasicDataSourceFactory().createDataSource(pro);
            //2.獲取連接對(duì)象
            con=bds.getConnection();
            //3.準(zhǔn)備sql語(yǔ)句
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
#dbcp.properties
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=123456
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC

在此過(guò)程中出現(xiàn)的問(wèn)題

數(shù)據(jù)庫(kù)常用連接池總結(jié)

解決方法 添加tomcat斌目錄下的tomcat-juli.jar

數(shù)據(jù)庫(kù)常用連接池總結(jié)


數(shù)據(jù)庫(kù)常用連接池總結(jié)

解決方法:

  1. DBCP連接池配置文件中的key與BasicDataSouce中的屬性一樣
  2. URl后追加allowPublicKeyRetrieval=true

數(shù)據(jù)庫(kù)常用連接池總結(jié)

C3P0連接池:
最常用的連接池技術(shù)!Spring框架,默認(rèn)支持C3P0連接池技術(shù)!
需要引入c3p0-0.9.1.2.jar
核心類:com.mchange.v2.c3p0.ComboPooledDataSourceimplements PooledDataSource extends DataSource

數(shù)據(jù)庫(kù)常用連接池總結(jié)

/*
     * 使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類--c3p0連接池硬編碼
     */
    @Test
    public void test4(){
        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            ComboPooledDataSource cpd=new ComboPooledDataSource();
            cpd.setDriverClass(driverClassName);
            cpd.setJdbcUrl(url);
            cpd.setUser(userName);
            cpd.setPassword(userPassword);
            //2.獲取連接對(duì)象
            con=cpd.getConnection();
            //3.準(zhǔn)備sql語(yǔ)句
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
/*
     * 使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類--c3p0連接池配置文件xml
     */
    @Test
    public void test5(){
        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            ComboPooledDataSource cpd=new ComboPooledDataSource("mysql-config");
            //ComboPooledDataSource cpd=new ComboPooledDataSource();
            //2.獲取連接對(duì)象
            con=cpd.getConnection();
            //3.準(zhǔn)備sql語(yǔ)句
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
<!--自動(dòng)加載src下c3p0的配置文件【c3p0-config.xml】,必須是放在src下。-->
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC</property>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123456</property>
    </default-config>
    <named-config name="mysql-config">
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC</property>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123456</property>
    </named-config>
</c3p0-config>

在此過(guò)程中出現(xiàn)的問(wèn)題

數(shù)據(jù)庫(kù)常用連接池總結(jié)

數(shù)據(jù)庫(kù)常用連接池總結(jié)

DRUID簡(jiǎn)介
Druid是阿里巴巴開(kāi)發(fā)的號(hào)稱為監(jiān)控而生的數(shù)據(jù)庫(kù)連接池。可以監(jiān)控?cái)?shù)據(jù)庫(kù)訪問(wèn)性能,Druid內(nèi)置提供了一個(gè)功能強(qiáng)大的StatView插件,能夠詳細(xì)統(tǒng)計(jì)SQL的執(zhí)行性能,這對(duì)于線上分析數(shù)據(jù)庫(kù)訪問(wèn)性能有幫助。
核心類 com.alibaba.druid.pool.DruidDataSource extends DruidAbstractDataSource implements DataSource

數(shù)據(jù)庫(kù)常用連接池總結(jié)

    /*
     * 使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類--druid連接池硬編碼
     */
    @Test
    public void test6(){
        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            DruidDataSource dds=new DruidDataSource();
            dds.setDriverClassName(driverClassName);
            dds.setUrl(url);
            dds.setUsername(userName);
            dds.setPassword(userPassword);
            //2.獲取連接對(duì)象
            con=dds.getConnection();
            //3.準(zhǔn)備sql語(yǔ)句
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
/*
     * 使用實(shí)現(xiàn)了javax.sql.DataSource接口的子類--druid連接池軟編碼
     */
    @Test
    public void test7(){
        try {
            //1.驅(qū)動(dòng)注冊(cè)程序
            Properties pro=new Properties();
            DataSource dds=null;
            InputStream inStream=SqlDriverManage.class.getResourceAsStream("druid.properties");
            pro.load(inStream);
            dds=com.alibaba.druid.pool.DruidDataSourceFactory.createDataSource(pro);

            //2.獲取連接對(duì)象
            con=dds.getConnection();
            //3.準(zhǔn)備sql語(yǔ)句
            String sql="select * from user";
            //4.創(chuàng)建prepareStatement
            pst=con.prepareStatement(sql);
            //5.執(zhí)行sql語(yǔ)句,得到返回結(jié)果
            rs= pst.executeQuery();
            //6.遍歷結(jié)果,索引從1開(kāi)始
            while(rs.next()){
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
#druid.properties
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=123456
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=truecharacterEncoding=UTF-8&useSSL=false&serverTimezone=UTC

網(wǎng)站題目:數(shù)據(jù)庫(kù)常用連接池總結(jié)
標(biāo)題網(wǎng)址:http://bm7419.com/article20/psopjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開(kāi)發(fā)移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站制作品牌網(wǎng)站建設(shè)、微信小程序企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化