代理实现连接池第三方连接池Dbutilsc3p0.docx

上传人:b****6 文档编号:7319902 上传时间:2023-01-22 格式:DOCX 页数:23 大小:337.66KB
下载 相关 举报
代理实现连接池第三方连接池Dbutilsc3p0.docx_第1页
第1页 / 共23页
代理实现连接池第三方连接池Dbutilsc3p0.docx_第2页
第2页 / 共23页
代理实现连接池第三方连接池Dbutilsc3p0.docx_第3页
第3页 / 共23页
代理实现连接池第三方连接池Dbutilsc3p0.docx_第4页
第4页 / 共23页
代理实现连接池第三方连接池Dbutilsc3p0.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

代理实现连接池第三方连接池Dbutilsc3p0.docx

《代理实现连接池第三方连接池Dbutilsc3p0.docx》由会员分享,可在线阅读,更多相关《代理实现连接池第三方连接池Dbutilsc3p0.docx(23页珍藏版)》请在冰豆网上搜索。

代理实现连接池第三方连接池Dbutilsc3p0.docx

代理实现连接池第三方连接池Dbutilsc3p0

代理实现连接池,第三方连接池,Dbutils

GenericServlet继承增强了HttpServlet(包装)

IO都是包装

BufferedReaderrd=newBufferedReader(newFileReader(“a.txt”));

BufferedReader增强了FileReader,从而可以由一个字符一个字符的读增强到可以到一行一行的读。

包装缺点:

1.需要实现的方法太多。

2.一个包装类,只可以包装一个被包装类。

如一个包装盒只可以包装一个蛋糕。

3.包装类也是被包装类(被包装的蛋糕,还是蛋糕)

对一个类增强的三种方式:

1.继承某个类extends

2.对某个类进行包装

3.动态代理

代理

代理的特点:

1.可以代理多个被代理类。

2.代理类不是被代理类,即经济人不是华仔。

3.代理可以在不污染任何类的情况下,对某个类进行代理。

代理的要求:

1.被代理的类必须要拥有一个接口。

2.代理的核心类:

●java.lang.reflect.Proxy–代理生成类

●java.lang.invokeHandler–执行句柄,可以在运行时获取正在调用某个方法,还有传递的参数

第一步:

如果要实现代理,某类必须要拥有一个接口。

Proxy(代理)在运行时根据给定的接口,在内存中创建一个与被代理类相同的类。

第二步:

示例代码

publicclassProxyDemo{

publicstaticvoidmain(String[]args){

System.err.println("1:

声明被代理类的实例");

finalCatcat=newCat();

System.err.println("2:

通过Proxy在内存中创建ICat的子类");

ObjectproxyedObj=Proxy.newProxyInstance(

ProxyDemo.class.getClassLoader(),newClass[]{Animal.class},

//拦截句柄,在执行时,只要执行代理类(经济人,中介-proxyedObj)任何方法,

//都会被这个句柄给拦截到

newInvocationHandler(){

//1:

参数:

proxy即proxyedObj,即这个一个代理,经济人,中介

//2:

Method即反射出来的代理对象的方法proxyedObj.getClass().getMethod(xx)

//3:

参数列表

publicObjectinvoke(Objectproxy,Methodmethod,

Object[]args)throwsThrowable{

System.err.println("5:

正在执行的方法为:

"+method.getName());

//如果没有返回则为null,调用cat对象的eat方法

ObjectreturnValue=method.invoke(cat,args);

System.err.println("7:

返回的值是:

"+returnValue);

returnreturnValue;

}

});

System.err.println("3:

将proxyedObj代理类,即经济人转成被代理对象");

Animala1=(Animal)proxyedObj;

System.err.println("4:

调用代理对象的(经济人的)eat方法");

a1.eat();

System.err.println("8:

执行完成");

}

}

//声明被代理类的class

interfaceAnimal{

publicvoideat();

}

classCatimplementsAnimal{

publicvoideat(){

System.err.println("6:

fishing...");

}

}

案例:

要求拦截List接口的添加元素方法。

分析:

即拦截List.add方法

/**

*拦截List添加方法

*/

publicclassInterListDemo{

publicstaticvoidmain(String[]args){

//1:

声明被代理的list

finalListlist=

newArrayList();

list.add("World");

//2:

在内存中创建List接口的子类

ObjectproxyedObj=

Proxy.newProxyInstance(InterListDemo.class.getClassLoader(),

newClass[]{List.class},

newInvocationHandler(){

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)

throwsThrowable{

System.err.println("正在执行某个方法:

"+method.getName());

//判断是否是正在执行size方法

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

return100;

}else{//否则,即调用的不是size方法,直接去执行原对象的某个方法

ObjectreturnValue=method.invoke(list,args);

returnreturnValue;

}

}

});

//3:

转换

Listlist2=(List)proxyedObj;

//list2.add("Hello");

//要求当调用size时不管原list中的size是多少,都返回100

System.err.println("list.size:

"+list2.size());

for(Objecto:

list2){

System.err.println(o);

}

}

}

 

代理实现连接池

用代理实现对Connection的close方法修改,目的要求不能关闭连接,应该是归还连接。

1.必须要有一个池,即List,LinkedList

2.创建多个连接入到List中去,在放之前,必须要对Connection进行代理

3.在代理的Connection方法中对所有其它方法都直接去调用原类即被代理类的方法,但对于close方法不能调用,应是修改为归还连接。

实现代码:

publicclassConnPool{

privatestaticLinkedListpool=

newLinkedList();

static{

try{

Propertiesp=

newProperties();

InputStreamin=

ConnPool.class.getClassLoader().getResourceAsStream("jdbc.properties");

p.load(in);

Stringdriver=p.getProperty("d");

Stringurl=p.getProperty("u");

Stringnm=p.getProperty("n");

Stringpwd=p.getProperty("p");

Integersize=Integer.valueOf(p.getProperty("s"));

//创建多个连接

for(inti=0;i

finalConnectioncon=//原生对象,即没有被代理的,但准备被代理的-华仔

DriverManager.getConnection(url,nm,pwd);

//声明代理类

ObjectconnProxy=

Proxy.newProxyInstance(

ConnPool.class.getClassLoader(),

newClass[]{Connection.class},

newInvocationHandler(){

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)

throwsThrowable{

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

System.err.println("有人还连接了");

synchronized(pool){

//由于proxy就是connProxy,所以直接就将proxy添加回去就可以

pool.addLast((Connection)proxy);

pool.notify();

}

returnnull;

}else{

//如果调用的不是close方法则直接调用原生对象的方法即放行

returnmethod.invoke(con,args);

}

}

});

//将代理类,即经济人放到List中

pool.add((Connection)connProxy);

}

}catch(Exceptione){

e.printStackTrace();

}

}

publicstaticConnectiongetCon(){

synchronized(pool){

//计算时间的开始

longstart=System.currentTimeMillis();

while(pool.size()==0){

//进入等待池

System.err.println("取一次:

"+Thread.currentThread().getName());

try{

pool.wait(1000);

}catch(InterruptedExceptione){

e.printStackTrace();

}

//计算时间是否超过了三秒

longpro=System.currentTimeMillis()-start;

if(pro>3000){

System.err.println("已经超过3秒超时,放弃");

thrownewRuntimeException("时间超时了");

}

}

System.err.println(pool.size());

Connectioncon=pool.removeFirst();

returncon;

}

}

}

 

标准连接池

标准的连接池,就是实现DataSource接口,且实现DataSource接口的类,必须是具体类,没有静态方法。

ConnectiongetConnection()

AttemptstoestablishaconnectionwiththedatasourcethatthisDataSourceobjectrepresents.

尝试建立与此DataSource对象所表示的数据源的连接。

ConnectiongetConnection(Stringusername,Stringpassword)

AttemptstoestablishaconnectionwiththedatasourcethatthisDataSourceobjectrepresents.

尝试建立与此DataSource对象所表示的数据源的连接。

实现以上的两个方法:

1.基本实现–生成标准的Connection对象。

2.连接池实现–生成自动参与连接池的Connection对象。

此实现与中间层连接池管理器一起使用。

实现代码:

publicclassMyDataSourceimplementsDataSource{

//1:

声明池对象

privateLinkedListpool=

newLinkedList();

//2:

为了向pool中放connection必须要只,能通过构造初始化多个连接

publicMyDataSource(){

try{

Propertiesp=

newProperties();

InputStreamin=

MyDataSource.class.getClassLoader()

.getResourceAsStream("jdbc.properties");

p.load(in);

Stringdriver=p.getProperty("d");

Stringurl=p.getProperty("u");

Stringnm=p.getProperty("n");

Stringpwd=p.getProperty("p");

Integersize=Integer.valueOf(p.getProperty("s"));

//创建多个连接

for(inti=0;i

finalConnectioncon=//原生对象,即没有被代理的,但准备被代理的-华仔

DriverManager.getConnection(url,nm,pwd);

//声明代理类

ObjectconnProxy=

Proxy.newProxyInstance(

ConnPool.class.getClassLoader(),

newClass[]{Connection.class},

newInvocationHandler(){

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)

throwsThrowable{

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

System.err.println("有人还连接了");

synchronized(pool){

//由于proxy就是connProxy,所以直接就将proxy添加回去就可以

pool.addLast((Connection)proxy);

pool.notify();

}

returnnull;

}else{

//如果调用的不是close方法则直接调用原生对象的方法即放行

returnmethod.invoke(con,args);

}

}

});

//将代理类,即经济人放到List中

pool.add((Connection)connProxy);

}

}catch(Exceptione){

e.printStackTrace();

}

}

publicConnectiongetConnection()throwsSQLException{

synchronized(pool){

//计算时间的开始

longstart=System.currentTimeMillis();

while(pool.size()==0){

//进入等待池

System.err.println("取一次:

"+Thread.currentThread().getName());

try{

pool.wait(1000);

}catch(InterruptedExceptione){

e.printStackTrace();

}

//计算时间是否超过了三秒

longpro=System.currentTimeMillis()-start;

if(pro>3000){

System.err.println("已经超过3秒超时,放弃");

thrownewRuntimeException("时间超时了");

}

}

System.err.println(pool.size());

Connectioncon=pool.removeFirst();

returncon;

}

}

如何使用:

通过第三方框架连接数据库

由于操作数据库,管理连接池,回收连接是JDBC必须要做的事,所以就有了第三方框架。

目前比较流行的连接池框架:

●dbcp-apache公司的dbcp=DataBaseConnectionPool版本1.2

●c3p0–0.9.1.2

●proxool–1.1

dbcp数据源

第一步:

导包

第二步:

dbcp核心类–声明一个类,用核心类连接数据库

BasicDataSource–它是javax.sql.DataSource子类。

对DataSource来说,它只是一个池,至于里面有没有连接,能不能连接到数据库,必须要通过dataSource.getConnection()测试。

如果只判断dataSource是否为null是不能确定是否连接数据库成功与否的。

c3p0数据源

c3p0的核心类:

ComboPooledDataSource–通过读取一个配置文件–配置文件必须是classpath:

c3p0-config.xml

第一步:

导包

第二步:

准备c3p0配置文件

第三步:

配置连接数据库的数据

xmlversion="1.0"encoding="UTF-8"?

>

--必须以c3p0-config开始-->

--在c3p0的配置文件中没有dtd定义-->

--必须要包含默认的配置项目-->

--配置驱动器-->

com.mysql.jdbc.Driver

[CDATA[jdbc:

mysql:

//127.0.0.1:

3306/day14?

useUnicode=true&characterEncoding=UTF-8]]>

root

1234

--初始化个数-->

2

--最少有多少个连接-->

2

--最多有多少个-->

4

--如果池中数据连接不够时一次增长多少个-->

3

--一个连接每一次最多执行多少个sql语句-->

50

第四步:

书写一个类,创建ComboPooledDataSource实例

publicclassDataSouceUtils{

//1:

声明ds的成员,一个项目中只要有一个ds就可以了

privatestaticDataSourceds;

//2:

在静态代码块中

static{

//如果直接实例化cpds则默认读取c3p0-config.xml中的默认配置

//如果带有参数,就会读取命名的配置

ds=newComboPooledDataSource();

}

//3:

提供一个静态方法返回ds实例

publicstaticDataSourcegetDataSource(){

returnds;

}

}

dbutils

定义

dbutils就是一个小型的hibenate。

就是将用户的CRUD工作都全部给封装了,用户通过简单的调用,就可以实现原来所有JDBC的一些功能。

(将statement.Query,execute,executeUpdate给封装了)

dbutils核心类

●QueryRunner,核心查询的类(select,update,delete,insert),相

展开阅读全文
相关搜索

当前位置:首页 > 初中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1