本文目录: 

      1、应用程序直接获取连接的缺点(图解) 

      2、使用数据库连接池优化程序性能(图解) 

      3、可扩展增强某个类方法的功能的三种方式 

      4、自定义数据库连接池——基于装饰设计模式

      5、数据库连接池核心代码——基于动态代理技术 

      6、开源数据库连接池介绍 

      7、DBCP数据源 

      8、DBCP数据源与应用服务器整合使用——  配置Tomcat数据源

       9、C3P0 数据源 

      10、JNDI技术简介 

1、应用程序直接获取连接的缺点(图解)

2、使用数据库连接池优化程序性能(图解)

3、可扩展增强某个类方法的功能的三种方式

(1) 在实际开发中,发现对象的方法满足不了开发需求时,有三种方式对其进行增强:

(a)创建该类的子类,并覆盖相应的方法;(较少使用)

(b)使用装饰(包装)设计模式;(可以使用,但有时书写的方法太多)

(c)使用动态代理技术。(最优的方式。)

(2) 使用子类覆盖父类方法的方式来增强功能的弊端:

需要将被增强父类的其他所需信息也要传递到子类中,而在开发中,经常无法知晓这些所需信息,所以使用子类覆盖被增强类方法的方式只是用于被增强类的内容较为简单的情景。

(3) 使用包装设计模式增强某个类方法的步骤:

(a) 定义一个类,实现与被增强类相同的接口;

(b) 在类中定义一个变量,记住被增强对象;

(c) 定义一个构造函数,接收被增强对象;

(d) 覆盖想增强的方法;

(e) 对于不想增强的方法,直接调用目标对象(被增强对象)的方法。

4、自定义数据库连接池——基于装饰设计模式

  编写连接池需实现java.sql.DataSource接口。DataSource接口中定义了两个重载的getConnection方法:

Connection   getConnection()

Connection  getConnection(String username, String password)

  实现DataSource接口,并实现连接池功能的步骤:

(1) 在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。

(2) 实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。

(3) 当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。

Collection保证将自己返回到LinkedList中是此处编程的难点。

Demo样例:自定义数据库连接池     (附件:JdbcPool.java)

  public class JdbcPool implements DataSource {
private static LinkedList<Connection> list = new LinkedList<Connection>();
private static Properties config = new Properties();
static{
try {
config.load(JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("db.properties"));
// 以配置文件方式 读取数据库配置信息。
Class.forName(config.getProperty("driver"));
for(int i=0;i<10;i++){
Connection conn = DriverManager.getConnection(config.getProperty("url"), config.getProperty("username"), config.getProperty("password"));
list.add(conn);
}
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
//conn.close() 此方法会将连接返回给数据库,所以不可用,需要自定义增强其功能,将连接返回到List集合中。
/* 在实际开发,发现对象的方法满足不了开发需求时,有三种方式对其进行增强
* 1.写一个connecton子类,覆盖close方法,增强close方法
* 2.用包装设计模式
* 3.用动态代理 aop 面向切面编程
*/
public Connection getConnection() throws SQLException {
if(list.size()<=0){
throw new RuntimeException("数据库忙,请稍会再来!!");
}
Connection conn = list.removeFirst(); //mysqlconnection C
MyConnection my = new MyConnection(conn); 调用自定义链接。
return my; //my-------preparedStatement commit createStatement close
}
// 内部类,当然也可以使用外部类
class MyConnection implements Connection{ //1.定义一个类,实现与被增强相同的接口
private Connection conn; //2.在类中定义一个变量,记住被增强对象
public MyConnection(Connection conn){ //3.定义一个构造函数,接收被增强对象
this.conn = conn;
}
public void close(){ //4.覆盖想增强的方法
list.add(this.conn);
}
//5.对于不想增强的方法,直接调用目标对象(被增强对象)的方法
public void clearWarnings() throws SQLException {
this.conn.clearWarnings();
}
public void commit() throws SQLException {
this.conn.commit();
}
public Statement createStatement() throws SQLException {
return this.conn.createStatement();
}
以下省略其他32个 不想增强的方法。(装饰模式的缺点,会实现许多不需要增强的方法) ……………… }
public Connection getConnection(String username, String password)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public void setLogWriter(PrintWriter arg0) throws SQLException {
// TODO Auto-generated method stub
}
public void setLoginTimeout(int arg0) throws SQLException {
// TODO Auto-generated method stub
}

5、数据库连接池核心代码——基于动态代理技术

使用动态代理技术构建连接池中的connection

proxyConn = (Connection) Proxy.newProxyInstance(this.getClass().getClassLoader(), conn.getClass().getInterfaces(),

new InvocationHandler() {

//此处为内部类,当close方法被调用时将conn还回池中,其它方法直接执行

public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {

if (method.getName().equals("close")) {

pool.addLast(conn);

return null;

}

return method.invoke(conn, args);

}

}

);

6、开源数据库连接池介绍

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

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

DBCP 数据库连接池 (Tomcat内置)

C3P0 数据库连接池(Spring内置)

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

备注:简单地讲,使用开源数据源,就是为了获取其DataSource对象,然后通过该对象动态的地获取数据库连接。

7、DBCP数据源

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

Commons-dbcp.jar:连接池的实现

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

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

使用DBCP示例代码:

static{

InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");

Properties prop = new Properties();

prop.load(in);

BasicDataSourceFactory factory = new BasicDataSourceFactory();

dataSource = factory.createDataSource(prop);

}

Demo样例1:JDBC 数据库连接池 由应用程序独立使用。

 public class JdbcUtils_DBCP {
private static DataSource ds = null;
static{
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("2013-06-10 11:26");
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 SQLException{
return ds.getConnection();
}
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();
}
}
}
}

Demo样例2: dbcpconfig.properties 文件的内容(也可参见附件)

 #连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day16
username=root
password=root #<!-- 初始化连接 -->
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)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_COMMITTED

8、DBCP数据源与应用服务器整合使用——  配置Tomcat数据源

查看Tomcat文档(Tomcat-->TomcatDocument-->JNDI Resources-->定位到JDBC Data Sources),示例代码:

<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/jdbc"  maxActive="8" maxIdle="4"  />

<Resource name="jdbc/EmployeeDB " 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>

放置位置:在MyEclipse中,在目录/META-INF/下创建文件context.xml,将上述内容粘贴其中(注:不要写XML文件的指令头句)。该文件将被发布到Tomcat服务器的conf\Catalina\localhost目录中,并以工程名称 命名该文件。

下面是调用JNDI,获取存储在JNDI容器中的资源的固定格式代码(有关JNDI的知识,参见下一章节):

Context initCtx = new InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

dataSource = (DataSource)envCtx.lookup("jdbc/datasource");

特别提醒:此种配置下,驱动jar文件需放置在tomcat的lib下

可以创建工具类JDBCUtils,java来封装上面获取连接的代码。

Demo样例: 封装JNDI调用DataSource 获取连接的代码。

 public class JdbcUtils_Tomcat {
private static DataSource ds;
static {
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
}

9、C3P0 数据源

所需jar包:

c3p0-0.9.2-pre1.jar

mchange-commons-0.2.jar

c3p0-oracle-thin-extras-0.9.2-pre1.jar(注:连接oracle数据库时才导入,否则不用导入。)

(1) 使用独立程序编码的方式配置c3p0数据源(有关数据库的连接信息会被写入代码中,不够优雅)

步骤:1、导入jar包:

2、编码调用。

Demo:编码调用c3p0数据源获取连接。 

ComboPooledDataSource ds=new ComboPooledDataSource();

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

ds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc1");

ds.setUser("root");

ds.setPassword("root");

ds.setMaxPoolSize(40);

ds.setMinPoolSize(10);

ds.setInitialPoolSize(30);

Connection conn=ds.getConnection();

其他数据库的操作

………

(2) 使用配置文件的方式配置c3p0数据源

(a) 配置文件名称:c3p0-config.xml (必须准确使用该名称)

(b) 配置文件放置位置:src路径下或者是web-inf/classes都可以(都一样)。

(c) 配置文件名称:c3p0-config.xml 的内容:

 <?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config> <!-- 默认数据库连接池配置信息-->
<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">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config> <!-- 第二个数据库连接池配置信息-->
<named-config name="flx"> <!--自定义数据源连接信息,比如可以分别书写 mysql 和 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">root</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>

(d) 在页面的调用代码:ComboPooledDataSource ds =new ComboPooledDataSource(连接信息名);

备注:(a)此处对应 c3p0-config.xml 文件中 <named-config name="flx">  元素——指定名称的数据源。

(b)数据源名称不写,则自动在类路径下搜索并使用 “默认数据源”;

(c)若书写名称,同样会搜索并调用指定名称的数据源;

  Demo样例:配置文件方式配置c3p0数据源的调用代码 。

   public class JdbcUtils_C3P0 {
private static ComboPooledDataSource ds = null;
static{
try{
ds = new ComboPooledDataSource(); //没指定数据源名称,则使用默认数据源
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
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();
}
}
}
}

10、JNDI技术简介

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

其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

此部分内容简单了解,会用其调用Tomcat内置的DBCP数据源即可。

JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术的更多相关文章

  1. Spring JDBC模版以及三种数据库连接池的使用

    jar包版本有点乱,直接忽略版本号,将就一下. 这里引了aop包是因为在spring3版本之后用模版对数据库库操作时会出现问题,但是不会报错,也没有提示. 所以这里直接引入,以及之后会用到的DBCP与 ...

  2. 常用数据库连接池 (DBCP、c3p0、Druid) 配置说明

    1. 引言 1.1 定义 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库 ...

  3. java常用数据库连接池 (DBCP、c3p0、Druid) 配置说明

    1. 引言 1.1 定义 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库 ...

  4. DataSource - 常用数据库连接池 (DBCP、c3p0、Druid) 配置说明

    1. 引言 1.1 定义 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库 ...

  5. 常用数据库连接池 (DBCP、c3p0、Druid) 配置说明.RP

    1. 引言 1.1 定义 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库 ...

  6. 常用数据库连接池 (DBCP、c3p0、Druid) 配置说明(转)

    1. 引言 1.1 定义 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库 ...

  7. JDBC学习笔记(三)

    获取数据库的元信息metadata,里面有数据库特性的描述信息,如是否支持事务,是否支持批处理等. Connection conn = DriverManager.getConnection(url, ...

  8. java学习笔记41(数据库连接池 C3p0连接池)

    在之前的学习中,我们发现,我们需要频繁的创建连接对象,用完之后还需要在关闭资源,因为这些连接对象都是占资源的,但是又不得不创建,比较繁琐,为了解决这种情况,Java出现了数据库连接池: 数据库连接池的 ...

  9. JavaWeb基础—数据库连接池DBCP、C3P0

    一.基本概念 数据库连接池负责分配.管理和释放数据库连接 数据库连接池:(池用map来实现居多) 用处:为了可重用(销毁创建麻烦,开销大)(招培训老师的例子) 二.编写实现数据库连接池 池参数: 初识 ...

  10. 数据库连接池 dbcp与c3p0的使用区别

    众所周知,无论现在是B/S或者是C/S应用中,都免不了要和数据库打交道.在与数据库交 互过程中,往往需要大量的连接.对于一个大型应用来说,往往需要应对数以千万级的用户连接请求,如果高效相应用户请求,对 ...

随机推荐

  1. c#获取网页内容的三种方法

    1.webclient WebClient wc = new WebClient(); Stream stm = wc.OpenRead(str_url); StreamReader sr = new ...

  2. View的setOnClickListener的添加方法

    1)第一种,也是最长见的添加方法(一下都以Button为例) 1 Button btn = (Button) findViewById(R.id.myButton);2 btn .setOnClick ...

  3. C# 线程传参

    传参方式有两种: 1.创建带参构造方法类 传参 2.利用Thread.start(8)直接传参,该方法会接收一个对象,并将该对象传递给线程,因此在线程中启动的方法 必须接收object类型的单个参数. ...

  4. iframe滚动条的一些方法

    用iframe布局,会碰到浏览器右边出现2个滚动条,简单代码解决用iframe布局,会碰到浏览器右边出现2个滚动条, 简单代码解决,用下面的代码可以把浏览器本身的滚动条去掉,只留页面产生的滚动条: b ...

  5. cocos2dx-lua 批量打包及修改

    coco2dx目前大部分开发者肯定是用lua解决问题,问题来了,每次改一下lua配置可能你每次都得运行 cocos luacompile -p android 针对不同的平台,可能会有某些配置会略有不 ...

  6. 验证证书的安装之外部用户PC

      背景:使用一个域外的用户进行登录并验证   1.         用户登录浏览器下载CA证书或者证书链   2.         下载   3.         安装证书   4.         ...

  7. 《Cocos2d-x实战 C++卷》上线了-源码-样章-感谢大家的支持

    <Cocos2d-x实战 C++卷>上线了 感谢大家一直以来的支持! 全面介绍Cocos开发技巧,采用Cocos2d-x3.2版本,并且详细介绍跨平台移植已经多平台发布细节. · 各大商店 ...

  8. jqure 获取地址栏的参数

    从一个页面跳转到另外一个页面传参,我们用jqure得到参数需要两部分: 处理浏览器地址栏参数的方法: function GetQueryString(name) { var reg = new Reg ...

  9. Javascript Class

    做个记录,javascript 如何创建类? 有早期的,有原型的,有构造函数的 // early javascript object var o = {}; o.color = 'red'; o.sh ...

  10. ionic2 页面加载时图片添加的问题

    使用ionic2创建项目时,在app文件夹下有图片目录img 在home中引用图片,但是不论是用ng-src或者是src,代码如下: <ion-list> <ion-slides c ...