欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中JDBC連接池的基本原理及實(shí)現(xiàn)方式

 更新時(shí)間:2021年12月20日 09:54:49   作者:小調(diào)~  
本文詳細(xì)講解了Java中JDBC連接池的基本原理及實(shí)現(xiàn)方式,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、 應(yīng)用程序直接建立數(shù)據(jù)庫(kù)連接模型

應(yīng)用程序直接每次訪問(wèn)數(shù)據(jù)庫(kù)時(shí),都建立創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)的鏈接,這樣每次建立這樣的連接都需要耗費(fèi)的資源,當(dāng)同時(shí)有很多用戶在使用應(yīng)用程序時(shí),可能會(huì)導(dǎo)致應(yīng)用程序崩潰。

圖為應(yīng)用程序直接建立數(shù)據(jù)庫(kù)連接模型

二、使用數(shù)據(jù)庫(kù)連接池優(yōu)化模型

數(shù)據(jù)庫(kù)連接池的基本思路是,平時(shí)建立適量的數(shù)據(jù)庫(kù)的連接,放在一個(gè)集合中,當(dāng)有用戶需要建立數(shù)據(jù)庫(kù)連接的時(shí)候,直接到集合中取出一個(gè)數(shù)據(jù)庫(kù)連接對(duì)象(Connection),這樣不用再需要重新創(chuàng)建,這樣會(huì)節(jié)省大量的資源,當(dāng)用戶不需要在對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn)了,那么就將數(shù)據(jù)庫(kù)連接對(duì)象(Connection)重新放回到集合中,以便方便下次使用。

數(shù)據(jù)庫(kù)連接池優(yōu)化模型圖

1、關(guān)于連接池中的連接數(shù)量的一些規(guī)定:

  • (1)最小連接數(shù):是連接池一直保持的數(shù)據(jù)庫(kù)連接,所以如果應(yīng)用程序?qū)?shù)據(jù)庫(kù)連接的使用量不大,將會(huì)有大量的數(shù)據(jù)庫(kù)連接資源被浪費(fèi)(適量).
  • (2)最大連接數(shù):是連接池能申請(qǐng)的最大連接數(shù),如果數(shù)據(jù)庫(kù)連接請(qǐng)求超過(guò)次數(shù),后面的數(shù)據(jù)庫(kù)連接請(qǐng)求將被加入到等待隊(duì)列中,這會(huì)影響以后的數(shù)據(jù)庫(kù)操作。通常在使用完起始集合中的連接后,會(huì)再重新創(chuàng)建一些數(shù)據(jù)庫(kù)連接對(duì)象,用來(lái)滿足用戶需求,但是這種新建并不是無(wú)限制的。
  • (3)當(dāng)使用完的連接對(duì)象需要重新放回到集合中以備使用,但是超過(guò)最小連接數(shù)的連接在使用完不會(huì)馬上被釋放,他將被放到連接池中等待重復(fù)使用或是超時(shí)后最終被釋放。

2、編寫(xiě)數(shù)據(jù)庫(kù)連接池

簡(jiǎn)單思路為:創(chuàng)建一個(gè)類(lèi)繼承DataSource接口,在類(lèi)中實(shí)現(xiàn)靜態(tài)的加載出配置文檔db.properties文檔,并創(chuàng)建最小連接量的數(shù)據(jù)庫(kù)連接對(duì)象(Connection),添加到Linkedlist(選擇Linkedlist集合原因是便于增刪)集合中。重寫(xiě)getConnection()函數(shù),在getConnection()函數(shù)中實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接對(duì)象的獲取。

db.properties文檔

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8
username=root
password=tiger

jdbcConnectionInitSize=10

創(chuàng)建數(shù)據(jù)庫(kù)連接池:

package JDBC;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.logging.Logger;

import javax.sql.DataSource;

public class JdbcConnectionsPool implements DataSource {

    /*
     * 使用靜態(tài)塊代碼,初始化連接池,創(chuàng)建連接池的中最小鏈接數(shù)量連接,
     * 創(chuàng)建linkedlist集合,將這些連接放入集合中
     */
    //創(chuàng)建linkedlist集合
    private static LinkedList<Connection> linkedlist1=new LinkedList<Connection>();
    private static String driver;//
    private static String url;//
    private static String username;//數(shù)據(jù)庫(kù)登陸名
    private static String password;//數(shù)據(jù)庫(kù)的登陸密碼
    private static int jdbcConnectionInitSize;//最小連接數(shù)量
    private static int max=1; //當(dāng)前最大連接數(shù)量=max*jdbcConnectionInitSize
    static{
        //通過(guò)反射機(jī)制獲取訪問(wèn)db.properties文件
        InputStream is=JdbcConnectionsPool.class.getResourceAsStream("/db.properties");
        Properties prop=new Properties();
        try {
            //加載db.properties文件
            prop.load(is);
            //獲取db.properties文件中的數(shù)據(jù)庫(kù)連接信息
            driver=prop.getProperty("driver");
            url=prop.getProperty("url");
            username=prop.getProperty("username");
            password=prop.getProperty("password");
            jdbcConnectionInitSize=Integer.parseInt(prop.getProperty("jdbcConnectionInitSize"));

            Class.forName("com.mysql.jdbc.Driver");

            //創(chuàng)建最小連接數(shù)個(gè)數(shù)據(jù)庫(kù)連接對(duì)象以備使用
            for(int i=0;i<jdbcConnectionInitSize;i++){
                Connection conn=DriverManager.getConnection(url, username, password);
                 System.out.println("獲取到了鏈接" + conn);
                //將創(chuàng)建好的數(shù)據(jù)庫(kù)連接對(duì)象添加到Linkedlist集合中
                linkedlist1.add(conn);
            }


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    @Override
    public PrintWriter getLogWriter() throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        // TODO Auto-generated method stub

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        // TODO Auto-generated method stub

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        // TODO Auto-generated method stub
        return false;
    }

    /*
     * 實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接的獲取和新創(chuàng)建
     */
    @Override
    public Connection getConnection() throws SQLException {
         //如果集合中沒(méi)有數(shù)據(jù)庫(kù)連接對(duì)象了,且創(chuàng)建的數(shù)據(jù)庫(kù)連接對(duì)象沒(méi)有達(dá)到最大連接數(shù)量,可以再創(chuàng)建一組數(shù)據(jù)庫(kù)連接對(duì)象以備使用
         if(linkedlist1.size()==0&&max<=5){
             try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             for(int i=0;i<jdbcConnectionInitSize;i++){
               Connection conn=DriverManager.getConnection(url, username, password);
               System.out.println("獲取到了鏈接" + conn);
               //將創(chuàng)建好的數(shù)據(jù)庫(kù)連接對(duì)象添加到Linkedlist集合中
               linkedlist1.add(conn);
                }
             max++;
            }
        if(linkedlist1.size()>0){
            //從linkedlist集合中取出一個(gè)數(shù)據(jù)庫(kù)鏈接對(duì)象Connection使用
            Connection conn1=linkedlist1.removeFirst();
            System.out.println("linkedlist1數(shù)據(jù)庫(kù)連接池大小是" + linkedlist1.size());
            /*返回一個(gè)Connection對(duì)象,并且設(shè)置Connection對(duì)象方法調(diào)用的限制,
            *當(dāng)調(diào)用connection類(lèi)對(duì)象的close()方法時(shí)會(huì)將Connection對(duì)象重新收集放入linkedlist集合中。
            */
            return (Connection) Proxy.newProxyInstance(conn1.getClass().getClassLoader(),//這里換成JdbcConnectionsPool.class.getClassLoader();也行
                 conn1.getClass().getInterfaces(), new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(!method.getName().equalsIgnoreCase("close")){
                            return method.invoke(conn1, args);
                        }else{
                            linkedlist1.add(conn1);
                            System.out.println(conn1+"對(duì)象被釋放,重新放回linkedlist集合中!");
                            System.out.println("此時(shí)Linkedlist集合中有"+linkedlist1.size()+"個(gè)數(shù)據(jù)庫(kù)連接對(duì)象!");
                            return null;
                            }
                        }
                   });
        }else{
            System.out.println("連接數(shù)據(jù)庫(kù)失??!");
        }
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {

        return null;
    }

}

進(jìn)一步封裝一些相關(guān)數(shù)據(jù)庫(kù)的類(lèi)的方法

package JDBC;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcConnectionPoolTest {

        /**
        * @Field: pool
        *          數(shù)據(jù)庫(kù)連接池
        */
        private static JdbcConnectionsPool pool = new JdbcConnectionsPool();

        /**
        * @Method: getConnection
        * @Description: 從數(shù)據(jù)庫(kù)連接池中獲取數(shù)據(jù)庫(kù)連接對(duì)象
        * @return Connection數(shù)據(jù)庫(kù)連接對(duì)象
        * @throws SQLException
        */
        public static Connection getConnection() throws SQLException{
            return pool.getConnection();
        }

        /**
        * @Method: release
        * @Description: 釋放資源,
        * 釋放的資源包括Connection數(shù)據(jù)庫(kù)連接對(duì)象,負(fù)責(zé)執(zhí)行SQL命令的Statement對(duì)象,存儲(chǔ)查詢結(jié)果的ResultSet對(duì)象
        * @param conn
        * @param st
        * @param rs
        */
        public static void release(Connection conn,Statement st,ResultSet rs){
            if(rs!=null){
                try{
                    //關(guān)閉存儲(chǔ)查詢結(jié)果的ResultSet對(duì)象
                    rs.close();
                }catch (Exception e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            if(st!=null){
                try{
                    //關(guān)閉負(fù)責(zé)執(zhí)行SQL命令的Statement對(duì)象
                    st.close();
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if(conn!=null){
                try{
                    //關(guān)閉Connection數(shù)據(jù)庫(kù)連接對(duì)象
                    conn.close();
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

}

調(diào)試代碼:

package JDBC;

import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class TestJdbcPool {

    public static void main(String[] args) throws SQLException {
        //實(shí)例化封裝了有關(guān)數(shù)據(jù)庫(kù)類(lèi)方法類(lèi)的對(duì)象
        JdbcConnectionPoolTest jcpt=new JdbcConnectionPoolTest();
        //獲得數(shù)據(jù)庫(kù)連接對(duì)象
        Connection conn=jcpt.getConnection();
        //下面代碼是存儲(chǔ)過(guò)程的調(diào)用
        String s="call SP_select_nofilter6(?,?,?) ";
        CallableStatement cst=conn.prepareCall(s);
        cst.setInt(2, 2);
        cst.registerOutParameter(1, Types.VARCHAR);
        cst.registerOutParameter(3, Types.BLOB);
        ResultSet rs=cst.executeQuery();
        String name=cst.getString(1);
        Blob b=cst.getBlob(3);

        System.out.println("name:"+name+" Blob:"+b);
        //關(guān)閉所有的數(shù)據(jù)庫(kù)資源
        jcpt.release(conn, cst, rs);
    }
}

運(yùn)行結(jié)果:

獲取到了鏈接com.mysql.jdbc.Connection@5f184fc6
獲取到了鏈接com.mysql.jdbc.Connection@723279cf
獲取到了鏈接com.mysql.jdbc.Connection@4e50df2e
獲取到了鏈接com.mysql.jdbc.Connection@7cc355be
獲取到了鏈接com.mysql.jdbc.Connection@52cc8049
獲取到了鏈接com.mysql.jdbc.Connection@7530d0a
獲取到了鏈接com.mysql.jdbc.Connection@4fca772d
獲取到了鏈接com.mysql.jdbc.Connection@7cd84586
獲取到了鏈接com.mysql.jdbc.Connection@70177ecd
獲取到了鏈接com.mysql.jdbc.Connection@cc34f4d
linkedlist1數(shù)據(jù)庫(kù)連接池大小是9
name:xiao Blob:com.mysql.jdbc.Blob@5197848c
com.mysql.jdbc.Connection@5f184fc6對(duì)象被釋放,重新放回linkedlist集合中!
此時(shí)Linkedlist集合中有10個(gè)數(shù)據(jù)庫(kù)連接對(duì)象!

標(biāo)紅的代碼是比較重要的代碼段~,其中Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),返回一個(gè)指定接口的代理類(lèi)實(shí)例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序,loader參數(shù)定義代理類(lèi)的類(lèi)加載器,interfaces - 代理類(lèi)要實(shí)現(xiàn)的接口列表,h - 指派方法調(diào)用的調(diào)用處理程序 。

三、兩個(gè)開(kāi)源的數(shù)據(jù)庫(kù)連接池

在使用了數(shù)據(jù)庫(kù)連接池之后,在項(xiàng)目的實(shí)際開(kāi)發(fā)中就不需要編寫(xiě)連接數(shù)據(jù)庫(kù)的代碼了,直接從數(shù)據(jù)源獲得數(shù)據(jù)庫(kù)的連接。

1、dbcp連接

(1)導(dǎo)入相關(guān)jar包

commons-dbcp2-2.1.1.jar

commons-pool2-2.4.2.jar

commoms-logging-1.2.jar

(2)在項(xiàng)目根目錄增加配置文件dbcp.properties

#連接設(shè)置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy
username=root
password=XDP

#<!-- 初始化連接 -->
initialSize=10

#最大連接數(shù)量
maxActive=50

#<!-- 最大空閑連接 -->
maxIdle=20

#<!-- 最小空閑連接 -->
minIdle=5

#<!-- 超時(shí)等待時(shí)間以毫秒為單位 6000毫秒/1000等于60秒 -->
maxWait=60000


#JDBC驅(qū)動(dòng)建立連接時(shí)附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;]
#注意:"user" 與 "password" 兩個(gè)屬性會(huì)被明確地傳遞,因此這里不需要包含他們。
connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由連接池所創(chuàng)建的連接的自動(dòng)提交(auto-commit)狀態(tài)。
defaultAutoCommit=true

#driver default 指定由連接池所創(chuàng)建的連接的只讀(read-only)狀態(tài)。
#如果沒(méi)有設(shè)置該值,則“setReadOnly”方法將不被調(diào)用。(某些驅(qū)動(dòng)并不支持只讀模式,如:Informix)
defaultReadOnly=

#driver default 指定由連接池所創(chuàng)建的連接的事務(wù)級(jí)別(TransactionIsolation)。
#可用值為下列之一:(詳情可見(jiàn)javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

(3)程序?qū)崿F(xiàn)dbcp連接

代碼演示:

數(shù)據(jù)庫(kù)對(duì)象的代理類(lèi)(封裝Connection類(lèi)的一些方法)

package DBCP;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPUtil {
    private static DataSource ds;
    private static final String configFile="/dbcp.properties";

    public DBCPUtil(){
        //實(shí)例化properties對(duì)象用于加載配置文件
        Properties prop=new Properties();
        InputStream is=DBCPUtil.class.getResourceAsStream(configFile);
        try {
            prop.load(is);
            ds=BasicDataSourceFactory.createDataSource(prop);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /*
     * 獲取數(shù)據(jù)庫(kù)連接對(duì)象
     */
    public Connection getConn(){
        Connection conn=null;
        if(ds!=null){
            try {
                conn=ds.getConnection();
                conn.setAutoCommit(false);//設(shè)置禁止操作自動(dòng)提交的情況
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return conn;
        }
        return conn;
    }
    /*
     * 封裝數(shù)據(jù)庫(kù)相關(guān)資源的關(guān)閉工作
     */
    public void close(ResultSet rs,Statement st,Connection conn) throws SQLException{
        if(rs!=null){
                rs.close();
        }
        if(st!=null){
                st.close();
        }
        if(conn!=null){
            conn.close();
        }
    }
}

代碼調(diào)用:

package DBCP;

import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class DbcpTest {

    public static void main(String[] args) throws SQLException {
                //實(shí)例化數(shù)據(jù)庫(kù)連接的代理類(lèi)
                DBCPUtil dbcpUtil=new DBCPUtil();
                //獲得數(shù)據(jù)庫(kù)連接對(duì)象
                Connection conn=dbcpUtil.getConn();
                //下面代碼是存儲(chǔ)過(guò)程的調(diào)用
                String s="call SP_select_nofilter6(?,?,?) ";
                CallableStatement cst=conn.prepareCall(s);
                cst.setInt(2, 2);
                cst.registerOutParameter(1, Types.VARCHAR);
                cst.registerOutParameter(3, Types.BLOB);
                ResultSet rs=cst.executeQuery();
                String name=cst.getString(1);
                Blob b=cst.getBlob(3);

                System.out.println("name:"+name+" Blob:"+b);
                //關(guān)閉資源
                dbcpUtil.close(rs, cst, conn);
    }

}

運(yùn)行結(jié)果:

name:xiao Blob:com.mysql.jdbc.Blob@30946e09

2、c3p0連接池

c3p0是一個(gè)開(kāi)源的JDBC連接池,它實(shí)現(xiàn)了數(shù)據(jù)源和JNDI綁定支持JDBC3和JDBC2的標(biāo)準(zhǔn)擴(kuò)展

(1)導(dǎo)入相關(guān)的jar包

cc3p0-0.9.2-pre4.jar

mchange-commons-java-0.2.2.jar

如果是oracle數(shù)據(jù)庫(kù)還需要添加c3p0-oracle-thin-extras-0.9.2-pre1.jar

(2)在項(xiàng)目根目錄下增加配置文件

1)c3p0.properties

##配置除user,password,minpoolsize,maxpoolsize的參數(shù)
##[注意] 整數(shù)值不能有空格
#連接設(shè)置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8
username=root
password=tiger

#初始化時(shí)獲取三個(gè)連接,取值應(yīng)在minPoolSize與maxPoolSize之間。Default: 3
c3p0.initialPoolSize=10

#當(dāng)連接池中的連接耗盡的時(shí)候c3p0一次同時(shí)獲取的連接數(shù)。Default: 3
c3p0.acquireIncrement=3

#最大空閑時(shí)間,60秒內(nèi)未使用則連接被丟棄。若為0則永不丟棄。Default: 0
#maxIdleTime應(yīng)該小于MySQL的wait_timeout的值
c3p0.maxIdleTime=600

#定義在從數(shù)據(jù)庫(kù)獲取新連接失敗后重復(fù)嘗試的次數(shù)。Default: 30
c3p0.acquireRetryAttempts=5

#兩次連接中間隔時(shí)間,單位毫秒。Default: 1000
c3p0.acquireRetryDelay=1000

#連接關(guān)閉時(shí)默認(rèn)將所有未提交的操作回滾。Default: false
c3p0.autoCommitOnClose=false

#c3p0將建一張名為T(mén)est的空表,并使用其自帶的查詢語(yǔ)句進(jìn)行測(cè)試。如果定義了這個(gè)參數(shù)那么
#屬性preferredTestQuery將被忽略。你不能在這張Test表上進(jìn)行任何操作,它將只供c3p0測(cè)試
#使用。Default: null
#c3p0.automaticTestTable=

#獲取連接失敗將會(huì)引起所有等待連接池來(lái)獲取連接的線程拋出異常。但是數(shù)據(jù)源仍有效
#保留,并在下次調(diào)用getConnection()的時(shí)候繼續(xù)嘗試獲取連接。如果設(shè)為true,那么在嘗試
#獲取連接失敗后該數(shù)據(jù)源將申明已斷開(kāi)并永久關(guān)閉。Default: false
#c3p0.breakAfterAcquireFailure=false

#當(dāng)連接池用完時(shí)客戶端調(diào)用getConnection()后等待獲取新連接的時(shí)間,超時(shí)后將拋出
#SQLException,如設(shè)為0則無(wú)限期等待。單位毫秒。Default: 0
c3p0.checkoutTimeout=10000

#每60秒檢查所有連接池中的空閑連接。Default: 0
c3p0.idleConnectionTestPeriod=600

#JDBC的標(biāo)準(zhǔn)參數(shù),用以控制數(shù)據(jù)源內(nèi)加載的PreparedStatements數(shù)量。但由于預(yù)緩存的statements
#屬于單個(gè)connection而不是整個(gè)連接池。所以設(shè)置這個(gè)參數(shù)需要考慮到多方面的因素。
#如果maxStatements與maxStatementsPerConnection均為0,則緩存被關(guān)閉。Default: 0
c3p0.maxStatements=100

#maxStatementsPerConnection定義了連接池內(nèi)單個(gè)連接所擁有的最大緩存statements數(shù)。Default: 0
c3p0.maxStatementsPerConnection=0

#c3p0是異步操作的,緩慢的JDBC操作通過(guò)幫助進(jìn)程完成。擴(kuò)展這些操作可以有效的提升性能
#通過(guò)多線程實(shí)現(xiàn)多個(gè)操作同時(shí)被執(zhí)行。Default: 3
c3p0.numHelperThreads=3

2)c3p0-config.xml文檔

<?xml version="1.0" encoding="UTF-8"?>
<!--
c3p0-config.xml必須位于類(lèi)路徑下面
private static ComboPooledDataSource ds;
static{
    try {
        ds = new ComboPooledDataSource("MySQL");
    } catch (Exception e) {
        throw new ExceptionInInitializerError(e);
    }
}
-->

<c3p0-config>
    <!--
    C3P0的缺省(默認(rèn))配置,
    如果在代碼中“ComboPooledDataSource ds = new ComboPooledDataSource();”這樣寫(xiě)就表示使用的是C3P0的缺省(默認(rèn))配置信息來(lái)創(chuàng)建數(shù)據(jù)源
    -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8</property>
        <property name="user">root</property>
        <property name="password">tiger</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <!--
    C3P0的命名配置,
    如果在代碼中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”這樣寫(xiě)就表示使用的是name是MySQL的配置信息來(lái)創(chuàng)建數(shù)據(jù)源
    -->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8</property>
        <property name="user">root</property>
        <property name="password">tiger</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

</c3p0-config>

(3)編寫(xiě)類(lèi)文件,創(chuàng)建連接池

1)c3p0.properties配置文件情況下

數(shù)據(jù)庫(kù)對(duì)象的代理類(lèi)(封裝Connection類(lèi)的一些方法)

package C3P0;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Util {

    private static ComboPooledDataSource ds=new ComboPooledDataSource();

    /*
     * 獲取數(shù)據(jù)庫(kù)連接對(duì)象
     */
    public static Connection getConnection() throws SQLException{
        return ds.getConnection();
    }

    /*
     * 封裝數(shù)據(jù)庫(kù)相關(guān)資源的關(guān)閉工作
     */
    public void close(ResultSet rs,Statement st,Connection conn) throws SQLException{
        if(rs!=null){
                rs.close();
        }
        if(st!=null){
                st.close();
        }
        if(conn!=null){
            conn.close();
        }
    }
}

代碼調(diào)用:

package C3P0;

import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class C3P0Test {

    public static void main(String[] args) throws SQLException {
        C3P0Util c3p0Util=new C3P0Util();
        Connection conn=c3p0Util.getConnection();
        //下面代碼是存儲(chǔ)過(guò)程的調(diào)用
                String s="call SP_select_nofilter6(?,?,?) ";
                CallableStatement cst=conn.prepareCall(s);
                cst.setInt(2, 2);
                cst.registerOutParameter(1, Types.VARCHAR);
                cst.registerOutParameter(3, Types.BLOB);
                ResultSet rs=cst.executeQuery();
                String name=cst.getString(1);
                Blob b=cst.getBlob(3);

                System.out.println("name:"+name+" Blob:"+b);
                //關(guān)閉資源
                c3p0Util.close(rs, cst, conn);
    }
}

運(yùn)行結(jié)果:

二月 14, 2017 7:36:12 下午 com.mchange.v2.log.MLog
信息: MLog clients using java 1.4+ standard logging.
二月 14, 2017 7:36:13 下午 com.mchange.v2.c3p0.C3P0Registry
信息: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
二月 14, 2017 7:36:13 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 5, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 10000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2y4pm69mgrekqw18rvmvn|7aec35a, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2y4pm69mgrekqw18rvmvn|7aec35a, idleConnectionTestPeriod -> 600, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 600, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 100, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
name:xiao Blob:com.mysql.jdbc.Blob@31b7dea0

2)c3p0-config.xml配置文檔情況下

數(shù)據(jù)庫(kù)對(duì)象的代理類(lèi)(封裝Connection類(lèi)的一些方法)

package C3P0;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Util1 {

    private static ComboPooledDataSource ds;

    /*
     * 獲取數(shù)據(jù)庫(kù)連接對(duì)象
     */
    public static Connection getConnection() throws SQLException{
        //通過(guò)代碼創(chuàng)建C3P0數(shù)據(jù)庫(kù)連接池
        /*ds = new ComboPooledDataSource();
        ds.setDriverClass("com.mysql.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbcstudy");
        ds.setUser("root");
        ds.setPassword("XDP");
        ds.setInitialPoolSize(10);
        ds.setMinPoolSize(5);
        ds.setMaxPoolSize(20);*/

        //通過(guò)讀取C3P0的xml配置文件創(chuàng)建數(shù)據(jù)源,C3P0的xml配置文件c3p0-config.xml必須放在src目錄下
        //ds = new ComboPooledDataSource();//使用C3P0的默認(rèn)配置來(lái)創(chuàng)建數(shù)據(jù)源
        ds = new ComboPooledDataSource("MySQL");//使用C3P0的命名配置來(lái)創(chuàng)建數(shù)據(jù)源
        return ds.getConnection();
    }

    /*
     * 封裝數(shù)據(jù)庫(kù)相關(guān)資源的關(guān)閉工作
     */
    public void close(ResultSet rs,Statement st,Connection conn) throws SQLException{
        if(rs!=null){
                rs.close();
        }
        if(st!=null){
                st.close();
        }
        if(conn!=null){
            conn.close();
        }
    }
}

代碼調(diào)用:

package C3P0;

import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class C3P0Test1 {

    public static void main(String[] args) throws SQLException {
        C3P0Util1 c3p0Util1=new C3P0Util1();
        Connection conn=c3p0Util1.getConnection();
        //下面代碼是存儲(chǔ)過(guò)程的調(diào)用
                String s="call SP_select_nofilter6(?,?,?) ";
                CallableStatement cst=conn.prepareCall(s);
                cst.setInt(2, 2);
                cst.registerOutParameter(1, Types.VARCHAR);
                cst.registerOutParameter(3, Types.BLOB);
                ResultSet rs=cst.executeQuery();
                String name=cst.getString(1);
                Blob b=cst.getBlob(3);

                System.out.println("name:"+name+" Blob:"+b);
                //關(guān)閉資源
                c3p0Util1.close(rs, cst, conn);
    }
}

運(yùn)行結(jié)果:

二月 14, 2017 8:06:03 下午 com.mchange.v2.log.MLog
信息: MLog clients using java 1.4+ standard logging.
二月 14, 2017 8:06:03 下午 com.mchange.v2.c3p0.C3P0Registry
信息: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
二月 14, 2017 8:06:03 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 5, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 10000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> MySQL, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2y4pm69mgsgybs1qf3g8s|6e5e91e4, idleConnectionTestPeriod -> 600, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 600, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 100, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
name:xiao Blob:com.mysql.jdbc.Blob@c39f790

總結(jié):其實(shí)不管配置文件是c3p0.properties還是c3p0-config.xml,其代碼實(shí)現(xiàn)部分沒(méi)有多大區(qū)別,唯一區(qū)別可能就是c3p0-config.xml情況下可以調(diào)用含參的ComboPooledDataSource(String s)構(gòu)造函數(shù),兩個(gè)都可以調(diào)用其默認(rèn)的無(wú)參構(gòu)造函數(shù)。

3、dbcp和c3p0不同之處

dbcp c3p0
spring組織推薦使用 Hibernate組織推薦使用
強(qiáng)制關(guān)閉連接或者數(shù)據(jù)庫(kù)重啟后無(wú)法自動(dòng)重連 強(qiáng)制關(guān)閉連接或者數(shù)據(jù)庫(kù)重啟可以自動(dòng)連接
沒(méi)有自動(dòng)的去回收空閑連接的功能 自動(dòng)回收空閑的功能
DBCP提供最大連接數(shù)

c3p0提供最大空閑時(shí)間

dbcp并沒(méi)用相應(yīng)功能 c3p0可以控制數(shù)據(jù)源加載的prepareedstatement數(shù)量,并且可以設(shè)置幫助線程的數(shù)量來(lái)提升JDBC操作速度

以上所述是小編給大家介紹的Java中JDBC連接池的基本原理及實(shí)現(xiàn)方式,希望對(duì)大家有所幫助。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 一篇文章輕松搞懂Java中的自旋鎖

    一篇文章輕松搞懂Java中的自旋鎖

    隨著互聯(lián)網(wǎng)的蓬勃發(fā)展,越來(lái)越多的互聯(lián)網(wǎng)企業(yè)面臨著用戶量膨脹而帶來(lái)的并發(fā)安全問(wèn)題。這篇文章主要給大家介紹了關(guān)于Java中自旋鎖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • mybatis-plus  mapper中foreach循環(huán)操作代碼詳解(新增或修改)

    mybatis-plus mapper中foreach循環(huán)操作代碼詳解(新增或修改)

    這篇文章主要介紹了mybatis-plus mapper中foreach循環(huán)操作代碼詳解(新增或修改),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 解決@Value注解不能注入static修飾的屬性問(wèn)題

    解決@Value注解不能注入static修飾的屬性問(wèn)題

    這篇文章主要介紹了解決@Value注解不能注入static修飾的屬性問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • java中@SuppressWarnings注解用法詳解

    java中@SuppressWarnings注解用法詳解

    這篇文章主要介紹了java中@SuppressWarnings注解用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • SpringMVC @DeleteMapping注解無(wú)法獲取參數(shù)值問(wèn)題及解決

    SpringMVC @DeleteMapping注解無(wú)法獲取參數(shù)值問(wèn)題及解決

    這篇文章主要介紹了SpringMVC @DeleteMapping注解無(wú)法獲取參數(shù)值問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Java寫(xiě)入寫(xiě)出Excel操作源碼分享

    Java寫(xiě)入寫(xiě)出Excel操作源碼分享

    這篇文章主要介紹了Java寫(xiě)入寫(xiě)出Excel操作源碼分享,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java 垃圾回收機(jī)制詳解(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    Java 垃圾回收機(jī)制詳解(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    在系統(tǒng)運(yùn)行過(guò)程中,會(huì)產(chǎn)生一些無(wú)用的對(duì)象,這些對(duì)象占據(jù)著一定的內(nèi)存,如果不對(duì)這些對(duì)象清理回收無(wú)用對(duì)象的內(nèi)存,可能會(huì)導(dǎo)致內(nèi)存的耗盡,所以垃圾回收機(jī)制回收的是內(nèi)存。下面通過(guò)本文給大家詳細(xì)介紹java垃圾回收機(jī)制,一起學(xué)習(xí)吧
    2017-02-02
  • Java Spring IOC圖文詳解

    Java Spring IOC圖文詳解

    IoC是一種讓服務(wù)消費(fèi)者不直接依賴于服務(wù)提供者的組件設(shè)計(jì)方式,是一種減少類(lèi)與類(lèi)之間依賴的設(shè)計(jì)原則。下面通過(guò)本文給大家分享spring中ioc的概念,感興趣的朋友一起看看吧
    2021-09-09
  • spring 自動(dòng)注入AutowiredAnnotationBeanPostProcessor源碼解析

    spring 自動(dòng)注入AutowiredAnnotationBeanPostProcessor源碼解析

    這篇文章主要介紹了spring自動(dòng)注入AutowiredAnnotationBeanPostProcessor源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了如何簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02

最新評(píng)論