常用开源数据库连接池

作者: 小小蒜头 | 来源:发表于2017-09-29 21:38 被阅读79次

现在很多WEB服务器(Weblogic,WebSphere,Tomcat)都提供了DataSource的实现(连接池的实现),我们把DataSource的实现,按其英文含义称之为数据源,数据源中包含了数据库连接池的实现。

也有一些开源组织提供了数据源的独立实现:

  1. DBCP 数据库连接池
  2. C3P0 数据库连接池
  3. Tomcat内置的连接池(DBCP)

DBCP数据源

使用DBCP数据源,应用程序应在系统中增加如下两个jar文件:

commons-dbcp.jar:连接池的实现
commons-pool.jar:连接池实现的依赖库

Tomcat的连接池正式采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

dbcpConfig.properties 配置文件

#连接设置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/testbatch
username=root
password=root

#oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:orcl
#username=system
#password=itcast

#初始化连接
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位  6000毫秒/1000=60秒 -->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性的格式必须为这样:[属性名=property;]
#注意:"user"与"password"两个属性会被明确传递,因此这里不需要包含它们
connectionProperties=useUnicode=true;characterEncoding=utf8

#指定由连接池所创建的连接的自动提交(auto-commit)状态
defaultAutoCommit=false

#如果没有设置该值,则"setReadOnly"方法将不被调用。(某些驱动并不支持只读模式,如:Infomix)
defaultReadOnly

#driver default 指定由连接池所创建连接的事务级别(TransactionIsolation)
#可用值:NONE,READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE
defalutTransactionIsolation=READ_COMMITTED

JdbcUtils_dbcp 连接池

package cn.itcast.utils;

import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtils {

    private static DataSource ds = null;

    static {
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpConfig.properties");
            Properties prop = new Properties();
            prop.load(in);

            BasicDataSourceFactory factory = new BasicDataSourceFactory();

            //创建数据库连接池
            ds = factory.createDataSource(prop);
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Connection getConnection() throws Exception {
        return ds.getConnection();//不会把sql真正的connection返回
    }


    public static void release(Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();   //throw new
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (st != null) {
            try {
                st.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            st = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

结果测试

@Test
    public void TestDataSource() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            System.out.println(conn);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }

结果:jdbc:mysql://localhost:3306/testbatch, UserName=root@localhost, MySQL Connector Java

C3P0数据源

Spring里面内置的数据源也是C3P0。

所需要的jar文件:

c3p0-0.9.5.2.jar
mchange-commons-java-0.2.11.jar

package cn.itcast.utils;

/**
 * Created by yvettee on 2017/9/28.
 */

import com.mchange.v2.c3p0.ComboPooledDataSource;

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

public class JdbcUtils_c3p0 {
    private static ComboPooledDataSource cpds = null;

    static {
        try {
            cpds = new ComboPooledDataSource();
            cpds.setDriverClass("com.mysql.jdbc.Driver");
            cpds.setJdbcUrl("jdbc:mysql://localhost:3306/testbatch");
            cpds.setUser("root");
            cpds.setPassword("root");
            cpds.setMaxPoolSize(30);
            cpds.setMinPoolSize(5);
            cpds.setInitialPoolSize(10);
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Connection getConnection() throws Exception {
        return cpds.getConnection();//不会把sql真正的connection返回
    }


    public static void release(Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();   //throw new
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (st != null) {
            try {
                st.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            st = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

结果测试

@Test
    public void TestDataSource() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils_c3p0.getConnection();
            System.out.println(conn.getClass().getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils_dbcp.release(conn, ps, rs);
        }
    }

结果:里面包含日志信息和打印出来的东西

1.png

如图所示:写进配置文件里,根据C3P0提供的方法新建一个配置文件c3p0-config.xml,这个配置文件名必须是c3p0-config.xml,因为在new ComboPooledDataSource("mysql");,它会自动搜索名为c3p0-config.xml的配置文件。

1.png
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/testbatch</property>
        <property name="user">root</property>
        <property name="password">root</property>

        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">20</property>
        <property name="minPoolSize">5</property>
        <property name="maxStatements">200</property>
    </default-config>
    <!--在new ComboPooledDataSource();时将named-config中name值传进去,如果没传值,就使用<default-config>的配置-->
    <named-config name="mysql">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000
        </property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>
    </named-config>

    <named-config name="oracle">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000
        </property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>
    </named-config>
</c3p0-config>

修改之前的代码

static {
        try {
            cpds = new ComboPooledDataSource();
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

配置Tomcat数据源

配置方法在官方文档里都有写的:

配置方法
在这里,提示一下,Tomcat配置数据源的方式必须将用到的jar文件(包括驱动jar)都要放进Tomcat安装目录的lib目录下。

1. 在Tomcat安装目录下的conf文件夹的server.xml文件里配置

2. 在Tomcat安装目录下的Catalina文件下的localhost文件夹里新建XML文件配置

当Tomcat启动时,就会为web应用创建连接池,并且Tomcat会把创建的这个连接池以JNDI的方式绑定到name="jdbc/datasource",用的时候只需要检索这个name的值就可以拿到连接池了。

server.xml</Host>前面添加下面的信息:

Context:当前web应用

name:项目名

docBase:指定Web应用的文件路径,可以给定绝对路径,也可以给定相对于<Host>的appBase属性的相对路径,如果Web应用采用开放目录结构,则指定Web应用的根目录,如果Web应用是个war文件,则指定war文件的路径。(指定项目所在地址)

<Context name="/DataSource" docBase="DataSource">
  <Resource name="jdbc/datasource" auth="container"
        type="javax.sql.DataSource" username="root" password="root"
        driverClassName="com.mysql.jdbc.driver"
        url="jdbc:mysql://localhost:3306/jdbc"
        maxActive="8" maxIdle="4"/>
</Context>

到这里,就已经成功创建好一个连接池了。

Context initCtx = new InitialContext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
dataSource = (DataSource)envCtx.lookup("jdbc/datasource");

特别提醒:此种配置下,驱动jar文件需放置在tomcatlib下。

3. 在WEB应用的META-INF下新建context.cml文件进行配置

我这里用到的是IDEA开发工具

jndi.png

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Resource name="jdbc/DataSource" auth="container"
              type="javax.sql.DataSource"
              username="root"
              password="root"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/testbatch"
              initialSize="30"
              maxActive="10" maxIdle="4"/>
</Context>

然后还要在web.xml中进行如下配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- DB Connection Start -->

    <description>MySQL Test App</description>
    <resource-ref>
        <description>DB COnnection</description>
        <res-ref-name>jdbc/DataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</web-app>

在JDBCUtils工具类里获取连接

package cn.itcast.utils;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * Created by yvettee on 2017/9/29.
 */
public class JdbcUtils {
    private static DataSource ds = null;

    static {
        try {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            ds = (DataSource) envCtx.lookup("jdbc/DataSource");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

}

在dao层进行实现

package cn.itcast.dao;


import cn.itcast.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.SQLException;

public class DaoData {
    public void add() {
        Connection conn = null;
        try {
            conn = JdbcUtils.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println(conn.getClass().getName());
    }

}

servlet里测试结果

package cn.itcast.web;

import cn.itcast.dao.DaoData;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by yvettee on 2017/9/29.
 */
@WebServlet(name = "DataSourceServlet", urlPatterns = "/DataSourceServlet")
public class DataSourceServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        DaoData dao = new DaoData();
        dao.add();
    }
}

源代码:https://github.com/yvettee36/DataSource.git

相关文章

  • JDBC进阶学习笔记

    JDBC进阶 JDBC连接池 1. 常见的JDBC连接池 c3p0 开源连接池 druid 阿里的开源数据库连接池...

  • Spring Boot学习:如何使用Druid数据源

    Druid概述 Druid是阿里巴巴开源的一款非常优秀的数据库连接池。在Java应用程序开发中,常用的连接池还有D...

  • 池技术之common-pool2

    是什么 apache commons-pool是apache基金会的一个开源对象池组件,我们常用的数据库连接池dp...

  • 常用开源数据库连接池

    现在很多WEB服务器(Weblogic,WebSphere,Tomcat)都提供了DataSource的实现(连接...

  • JDBC 进阶——连接池

    本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...

  • DruidDataSource详解(一)

    资源复用是系统性能优化中的一种常用手段,如单例,数据库连接池,线程池等都是资源复用的常用技巧。 数据库连接池的基本...

  • Grails 3.2.3 如何把连接池换成Druid

    阿里开源的Java数据库连接池Druid(https://github.com/alibaba/druid/)...

  • Springboot 集成 Druid 数据源

    常用的连接池有:DBCP, C3P0,Proxool 等. Druid 是阿里系提供的一个开源连接池, 除在连接池...

  • Druid SQL 解析器

    认识 Druid Druid 是阿里巴巴公司开源的一个数据库连接池,它的口号是:为监控而生的数据库连接池 根据官方...

  • 据库连接池的原理

    这次我们采取技术演进的方式来谈谈数据库连接池的技术出现过程及其原理,以及当下最流行的开源数据库连接池jar包。 一...

网友评论

本文标题:常用开源数据库连接池

本文链接:https://www.haomeiwen.com/subject/zyovextx.html