本文目录: 

      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)

 1  public class JdbcPool implements DataSource {
 2       private static LinkedList<Connection> list = new LinkedList<Connection>();
 3       private static Properties config = new Properties();
 4       static{
 5             try {
 6                   config.load(JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("db.properties"));
 7                   // 以配置文件方式 读取数据库配置信息。
 8                   Class.forName(config.getProperty("driver"));
 9                   for(int i=0;i<10;i++){
10                         Connection conn = DriverManager.getConnection(config.getProperty("url"), config.getProperty("username"), config.getProperty("password"));
11                         list.add(conn);
12                   }
13             } catch (Exception e) {
14                   throw new ExceptionInInitializerError(e);
15             }
16       }
17       //conn.close()    此方法会将连接返回给数据库,所以不可用,需要自定义增强其功能,将连接返回到List集合中。
18       /* 在实际开发,发现对象的方法满足不了开发需求时,有三种方式对其进行增强
19        * 1.写一个connecton子类,覆盖close方法,增强close方法
20        * 2.用包装设计模式
21        * 3.用动态代理    aop 面向切面编程
22        */
23       public Connection getConnection() throws SQLException {
24             if(list.size()<=0){
25                   throw new RuntimeException("数据库忙,请稍会再来!!");
26             }
27             Connection conn = list.removeFirst();   //mysqlconnection   C
28             MyConnection my = new MyConnection(conn);    调用自定义链接。
29              return my;      //my-------preparedStatement   commit   createStatement  close
30       }
31       // 内部类,当然也可以使用外部类
32       class MyConnection implements Connection{      //1.定义一个类,实现与被增强相同的接口
33                 private Connection conn;      //2.在类中定义一个变量,记住被增强对象
34                 public MyConnection(Connection conn){    //3.定义一个构造函数,接收被增强对象
35                        this.conn = conn;
36                 }
37                 public void close(){     //4.覆盖想增强的方法
38                       list.add(this.conn);
39                 }
40                //5.对于不想增强的方法,直接调用目标对象(被增强对象)的方法
41                public void clearWarnings() throws SQLException {
42                       this.conn.clearWarnings();
43                 }
44                 public void commit() throws SQLException {
45                       this.conn.commit();
46                 }
47                 public Statement createStatement() throws SQLException {
48                       return this.conn.createStatement();
49                 }
50                 以下省略其他32个 不想增强的方法。(装饰模式的缺点,会实现许多不需要增强的方法)
51
52                  ………………
53
54          }
55           public Connection getConnection(String username, String password)
56               throws SQLException {
57             // TODO Auto-generated method stub
58             return null;
59           }
60           public PrintWriter getLogWriter() throws SQLException {
61             // TODO Auto-generated method stub
62             return null;
63           }
64           public int getLoginTimeout() throws SQLException {
65             // TODO Auto-generated method stub
66             return 0;
67           }
68           public void setLogWriter(PrintWriter arg0) throws SQLException {
69             // TODO Auto-generated method stub
70           }
71           public void setLoginTimeout(int arg0) throws SQLException {
72             // TODO Auto-generated method stub
73           }
74     } 

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 数据库连接池 由应用程序独立使用。

 1 public class JdbcUtils_DBCP {
 2           private static DataSource ds = null;
 3           static{
 4                 try{
 5                       InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("2013-06-10 11:26");
 6                       Properties prop = new Properties();
 7                       prop.load(in);
 8                       BasicDataSourceFactory factory = new BasicDataSourceFactory();
 9                       ds = factory.createDataSource(prop);
10                 }catch (Exception e) {
11                       throw new ExceptionInInitializerError(e);
12                 }
13           }
14           public static Connection getConnection() throws SQLException{
15             return ds.getConnection();
16           }
17           public static void release(Connection conn,Statement st,ResultSet rs){
18                 if(rs!=null){
19                       try{
20                             rs.close();   //throw new
21                       }catch (Exception e) {
22                             e.printStackTrace();
23                       }
24                       rs = null;
25                 }
26                 if(st!=null){
27                       try{
28                             st.close();
29                       }catch (Exception e) {
30                             e.printStackTrace();
31                       }
32                       st = null;
33                 }
34                 if(conn!=null){
35                       try{
36                             conn.close();
37                       }catch (Exception e) {
38                             e.printStackTrace();
39                       }
40                 }
41           }
42     } 

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

 1 #连接设置
 2 driverClassName=com.mysql.jdbc.Driver
 3 url=jdbc:mysql://localhost:3306/day16
 4 username=root
 5 password=root
 6
 7 #<!-- 初始化连接 -->
 8 initialSize=10
 9 #最大连接数量
10 maxActive=50
11 #<!-- 最大空闲连接 -->
12 maxIdle=20
13 #<!-- 最小空闲连接 -->
14 minIdle=5
15 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
16 maxWait=60000
17
18 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
19 #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
20 connectionProperties=useUnicode=true;characterEncoding=utf8
21
22 #指定由连接池所创建的连接的自动提交(auto-commit)状态。
23 defaultAutoCommit=true
24
25 #driver default 指定由连接池所创建的连接的只读(read-only)状态。
26 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
27 defaultReadOnly=
28
29 #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
30 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
31 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 获取连接的代码。

 1 public class JdbcUtils_Tomcat {
 2               private static DataSource ds;
 3               static {
 4                     try {
 5                           Context initCtx = new InitialContext();
 6                           Context envCtx = (Context) initCtx.lookup("java:comp/env");
 7                           ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");
 8                     } catch (Exception e) {
 9                           throw new RuntimeException(e);
10                     }
11               }
12               public static Connection getConnection() throws SQLException{
13                     return ds.getConnection();
14               }
15         }

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 的内容:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2     <c3p0-config>
 3      <default-config>        <!-- 默认数据库连接池配置信息-->
 4        <property name="driverClass">com.mysql.jdbc.Driver</property>
 5        <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>
 6        <property name="user">root</property>
 7        <property name="password">root</property>
 8        <property name="acquireIncrement">5</property>
 9        <property name="initialPoolSize">10</property>
10        <property name="minPoolSize">5</property>
11        <property name="maxPoolSize">20</property>
12      </default-config>
13
14  <!-- 第二个数据库连接池配置信息-->
15      <named-config name="flx">  <!--自定义数据源连接信息,比如可以分别书写 mysql  和 oracle 两个连接信息,以方便 换数据库。 注:此处对应调用代码中的“连接信息名” -->
16        <property name="driverClass">com.mysql.jdbc.Driver</property>
17        <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>
18        <property name="user">root</property>
19        <property name="password">root</property>
20        <property name="acquireIncrement">5</property>
21        <property name="initialPoolSize">10</property>
22        <property name="minPoolSize">5</property>
23        <property name="maxPoolSize">20</property>
24      </named-config>
25     </c3p0-config> 

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

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

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

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

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

 1   public class JdbcUtils_C3P0 {
 2           private static ComboPooledDataSource ds = null;
 3           static{
 4                 try{
 5                       ds = new ComboPooledDataSource();  //没指定数据源名称,则使用默认数据源
 6                 }catch (Exception e) {
 7                       throw new ExceptionInInitializerError(e);
 8                 }
 9           }
10           public static Connection getConnection() throws SQLException{
11                 return ds.getConnection();
12           }
13           public static void release(Connection conn,Statement st,ResultSet rs){
14                 if(rs!=null){
15                       try{
16                             rs.close();   //throw new
17                       }catch (Exception e) {
18                             e.printStackTrace
19                       }
20                       rs = null;
21                 }
22                 if(st!=null){
23                       try{
24                             st.close();
25                       }catch (Exception e) {
26                             e.printStackTrace();
27                       }
28                       st = null;
29                 }
30                 if(conn!=null){
31                       try{
32                             conn.close();
33                       }catch (Exception e) {
34                             e.printStackTrace();
35                       }
36                 }
37           }
38     } 

10、JNDI技术简介

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

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

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

转载于:https://www.cnblogs.com/lijiews/p/lj201401221547.html

JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术...相关推荐

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

    转载自  常用数据库连接池 (DBCP.c3p0.Druid) 配置说明 1. 引言 1.1 定义 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的 ...

  2. 数据库连接池 (DBCP、c3p0、Druid) 配置说明和对比

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

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

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

  4. javaweb mysql 连接池 c3p0 配置_JavaWeb基础—数据库连接池DBCP、C3P0

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

  5. 数据库连接池 DBCP和c3p0数据库连接池

    一.数据库连接池 1. 什么是连接池 传统的开发模式下,Servlet处理用户的请求,找Dao查询数据,dao会创建与数据库之间的连接,完成数据查询后会关闭数据库的链接. 这样的方式会导致用户每次请求 ...

  6. Java数据库连接池--DBCP浅析

    转载自   Java数据库连接池--DBCP浅析 前言对于数据库连接池, 想必大家都已经不再陌生, 这里仅仅设计Java中的两个常用数据库连接池: DBCP和C3P0(后续会更新). 一. 为何要使用 ...

  7. JDBC学习笔记03【JDBC事务管理、数据库连接池、JDBCTemplate】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  8. JDBC 学习笔记(一)—— 基础知识 + 分页技术

    2019独角兽企业重金招聘Python工程师标准>>> 本文查阅方法:     1.查阅目录 -- 查阅本文目录,确定想要查阅的目录标题     2.快捷"查找" ...

  9. jdbc mysql分页_JDBC【数据库连接池、DbUtils框架、分页】

    1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的... 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地打开.关闭连接造成系统性能低下 编写连接 ...

  10. JDBC第四篇【数据库连接池、DbUtils框架、分页】(修订版)

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 1.数据库连接池 什么是数据库连接池 简单来说:数据 ...

最新文章

  1. webscraper多页爬取_【实践】笔记_Chrome插件webscraper爬取天眼通数据
  2. 如何用 OpenCV、Python 和深度学习实现面部识别?
  3. mysql 使用真正的utf-8编码
  4. 最温暖的大学,最火热的比赛
  5. UWP 推荐 - 限时免费的RSS阅读器《RSS 追踪》登录 Windows 10
  6. 水晶报表,解决——提示“您请求的报表需要更多信息.”
  7. Kettle使用_8 存储过程结合获取系统信息
  8. 【C++深度剖析教程37】类模板的概念和意义
  9. 字符设备驱动高级篇2——字符设备驱动注册代码分析
  10. vlan划分不能上网_VLAN工作原理
  11. 浏览器展示CSS伪类的动画和过渡效果应用
  12. android之AlarmManager 全局定时器
  13. Ponemon Institute告诉你,大数据正在勾搭网络安全
  14. 支持Android的Qt5预览
  15. 软件项目组织与管理期末考试复习要点整理翻译
  16. Excel下拉框多选(支持再次选择已选项会取消选择)
  17. 支付宝当面付(统一收单线下交易预创建,二维码扫码支付)
  18. JavaScript设计模式之“单例模式“
  19. 装mysql电脑网卡不见了_网络适配器不见了怎么办【解决方法】
  20. 中旅投资计划战略入股开元森泊,成为其第二大股东

热门文章

  1. Mac操作指南:废纸篓里的文件无法清除如何解决?
  2. 如何在 Mac 上将 WebP 图像批量转换为 JPG?
  3. iClip mac如何自定义声音?iClip剪切板管理软件更改声音的方法
  4. xadmin 组件拓展自定义使用
  5. python全栈_010_Python3基本数据类型--元组
  6. CSS 控制滚动条样式
  7. 对于stackoverflow的中文翻译的相关问题
  8. 手把手搭建WAMP+PHP+SVN开发环境
  9. POI实现超大数据的Excel的读写操作
  10. Maven仓库—Nexus环境搭建及简单介绍