21.JDBC开发(4)开源数据库连接池(javaEE笔记)

一、开源数据库连接池

  • 现在很多web服务器都提供了DataSource的实现,即连接池的实现。通常我们把DataSource的实现按其英文含义称为数据源,数据源中都包含了数据库连接池的实现。

  • 也有一些开源组织提供了数据源的独立实现:
    DBCP数据库连接池
    C3P0数据库连接池
    使用tomcat数据源

  • 实际应用时不需要编写连接数据库代码,直接从数据源获得数据库的连接。程序员编写时也尽量使用这些数据源的实现,以提升程序的数据库访问性能。

二、DBCP数据源(工程day16

  • DBCP是Apache软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个jar文件:
    commons-dbcp.jar:连接池的实现
    commons-pool.jar:连接池实现的依赖库

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

使用此数据源需要一个配置文件:
dbcpconfig.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3305/day15
username=root
password=walp1314

#<!-- 初始化连接 -->
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=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可以看文档)NONE,READ_UNCOMMITED,READ_COMMITED,REPEATABLE_READ,SERIALIZABLE
#但是注意:以上是mysql的隔离级别,Oracle有些不同,Oracle最低要求READ_COMMITED
defaultTransactionIsolation=READ_UNCOMMITED

JdbcUtils_DBCP.java

package cn.itcast.utils;
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 JdbcUtils_DBCP {
    
    private static DataSource ds = null;
    static{
        try{
            InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);
            //先new一个工厂
            BasicDataSourceFactory factory = new BasicDataSourceFactory();
            //使用工厂生成数据源
            ds = factory.createDataSource(properties);
            System.out.println(ds);
        }catch(Exception e){
            throw new ExceptionInInitializerError(e);
        }
    }
    public static Connection getConnection() throws SQLException{
        return ds.getConnection();
    }
    
    
    public static void release(Connection conn, Statement ps , ResultSet result){
        if(result != null){
            try {
                result.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            result = null;
        }
        if(ps != null){
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            ps = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

说明:这里我们可以使用之前的例子(如Demo1.java)进行测试,但是当我们使用的DBCP是版本1,那么是可以测试成功的,但是如果用DBCP的版本2,那么会出现异常,此时我们需要再导入一个jar包:commons-logging-1.2.jar。这样才能测试成功。

C3P0数据源(工程day16

首先需要导入相关的jar包:

c3p0-0.9.5.1.jar
mchange-commons-java-0.2.10.jar

使用此数据源需要的配置文件是:
c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

    <!-- 如果在new的时候不指定使用哪个配置则使用下面缺省的配置  -->
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3305/day16</property>
    <property name="user">root</property>
    <property name="password">walp1314</property>
    <!-- 池里面的链接数量不够的时候可以再找数据库要多少个  -->
    <property name="acquireIncrement">5</property>
    <property name="initialPoolSize">10</property>
    <property name="minPoolSize">5</property>
    <property name="maxPoolSize">20</property>
  </default-config>

  <!-- This app is massive! -->
  <named-config name="mysql"> 
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>
    <property name="user">root</property>
    <property name="password">walp1314</property>

    <property name="acquireIncrement">5</property><!--池里面的链接数量不够的时候可以再找数据库要多少个  -->
    <property name="initialPoolSize">10</property>
    <property name="minPoolSize">5</property>
    <property name="maxPoolSize">20</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="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>
    <property name="user">root</property>
    <property name="password">walp1314</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>

说明:如果我们在后面程序中如果不指定使用哪个数据库配置,那么就使用默认的配置。

JdbcUtils_C3P0.java

package cn.itcast.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JdbcUtils_C3P0 {
    
    private static ComboPooledDataSource ds = null;
    static{
        try{
            //使用配置文件时,配置文件必须放在src下,同时配置文件名不要改,如果不指定配置文件名,则使用默认的配置
            ds = new ComboPooledDataSource("mysql");
        }catch(Exception e){
            throw new ExceptionInInitializerError(e);
        }
    }
    public static Connection getConnection() throws SQLException{
        return ds.getConnection();
    }
    
    public static void release(Connection conn, Statement ps , ResultSet result){
        if(result != null){
            try {
                result.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            result = null;
        }
        if(ps != null){
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            ps = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

说明:我们也可以直接在程序中对其驱动等信息进行设置,但是那样太麻烦,这里我们使用配置文件,如果不具体指定使用哪个配置,那就使用默认配置。同样我们可以使用之前的程序进行测试。

四、使用tomcat数据源(工程day16_web

我们可以在tomcat服务器中配置一个数据源,这个数据源使用的JNDI技术。

所谓JNDI:

  • JNDI(java Naming and Directory Interface),java命名和目录接口,它对应于J2SE中的javax.naming包。这套API的主要作用在于:它可以把java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得java对象,只需通过名称检索即可。
  • 其核心API为context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

首先我们需要配置tomcat的Context,配置Context可以有多种方式,这里我们使用一个配置文件放在META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/EmployeeDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="root"
            password="walp1314"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3305/day16"
            maxTotal="8"
            maxIdle="4"/>
</Context>

ServletDemo1.java

package cn.itcast.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.dao.BaseDao;
//记得mysql的驱动一定要加到tomcat的lib中
public class ServletDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        BaseDao dao = new BaseDao();
        dao.add();

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

BaseDao.java

package cn.itcast.dao;
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class BaseDao {
    
    public void add() {
        try {
            // 此时我们所有的程序都是在服务器中,在一般的类中我们也可以拿到数据库链接
            Context initCtx = new InitialContext();// 初始化JNDI
            Context envCtx = (Context) initCtx.lookup("java:comp/env");// 得到JNDI容器
            DataSource ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");// 从容器中检索一个链接池
            Connection conn = ds.getConnection();// 获取到一个链接
            System.out.println(conn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

说明:这里一定注意要将mysql的jdbc驱动放在tomcat的lib目录中。

最后:其实还有一些开源的数据源可以使用,比如阿里巴巴的数据源druid-1.0.19.jar,在以后的项目中可以使用,而且其功能强大。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,836评论 6 342
  • 本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...
    廖少少阅读 16,754评论 0 37
  • 主要内容 定义Spring的数据访问支持 配置数据库资源 使用Spring提供的JDBC模板 写在前面:经过上一篇...
    程序熊大阅读 8,772评论 1 31
  • 声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互...
    凯哥学堂阅读 1,047评论 0 0
  • 文|九月流云 风筝缘|总目录 上一章|(27)路遇歹徒 (28)肖秋病了 当肖秋洗完澡上床来的时候,袁丽掀开她的睡...
    九月流云阅读 431评论 10 19