首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
Linux资讯 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>java>java企业应用>正文

使用JAVA中的动态代理实现数据库连接池

http://www.oklinux.cn  2008-03-07  来源: 赛迪网 执木  会员收藏  游客收藏  【 】 

数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈。我们可以在互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共同的问题:这些连接池的实现方法都不同程度地增加了与使用者之间的耦合度。很多的连接池都要求用户通过其规定的方法获取数据库的连接,这一点我们可以理解,毕竟目前所有的应用服务器取数据库连接的方式都是这种方式实现的。但是另外一个共同的问题是,它们同时不允许使用者显式的调用Connection.close()方法,而需要用其规定的一个方法来关闭连接。这种做法有两个缺点:

第一:改变了用户使用习惯,增加了用户的使用难度。

首先我们来看看一个正常的数据库操作过程:


int executeSQL(String sql) throws SQLException
{
Connection conn = getConnection(); //通过某种方式获取数据库连接
PreparedStatement ps = null;
int res = 0;
try{
ps = conn.prepareStatement(sql);
res = ps.executeUpdate();
}finally{
try{
ps.close();
}catch(Exception e){}
try{
conn.close();//
}catch(Exception e){}
}
return res;
}




使用者在用完数据库连接后通常是直接调用连接的方法close来释放数据库资源,如果用我们前面提到的连接池的实现方法,那语句conn.close()将被某些特定的语句所替代。

第二:使连接池无法对之中的所有连接进行独占控制。由于连接池不允许用户直接调用连接的close方法,一旦使用者在使用的过程中由于习惯问题直接关闭了数据库连接,那么连接池将无法正常维护所有连接的状态,考虑连接池和应用由不同开发人员实现时这种问题更容易出现。

综合上面提到的两个问题,我们来讨论一下如何解决这两个要命的问题。

首先我们先设身处地的考虑一下用户是想怎么样来使用这个数据库连接池的。用户可以通过特定的方法来获取数据库的连接,同时这个连接的类型应该是标准的java.sql.Connection。用户在获取到这个数据库连接后可以对这个连接进行任意的操作,包括关闭连接等。

通过对用户使用的描述,怎样可以接管Connection.close方法就成了我们这篇文章的主题。

为了接管数据库连接的close方法,我们应该有一种类似于钩子的机制。例如在Windows编程中我们可以利用Hook API来实现对某个Windows API的接管。在JAVA中同样也有这样一个机制。JAVA提供了一个Proxy类和一个InvocationHandler,这两个类都在java.lang.reflect包中。我们先来看看SUN公司提供的文档是怎么描述这两个类的。


public interface InvocationHandler

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.

Each proxy instance has an associated invocation handler.
When a method is invoked on a proxy instance,
the method invocation is encoded and dispatched to the invoke method of its invocation handler.




SUN的API文档中关于Proxy的描述很多,这里就不罗列出来。通过文档对接口InvocationHandler的描述我们可以看到当调用一个Proxy实例的方法时会触发Invocationhanlder的invoke方法。从JAVA的文档中我们也同时了解到这种动态代理机制只能接管接口的方法,而对一般的类无效,考虑到java.sql.Connection本身也是一个接口由此就找到了解决如何接管close方法的出路。

首先,我们先定义一个数据库连接池参数的类,定义了数据库的JDBC驱动程序类名,连接的URL以及用户名口令等等一些信息,该类是用于初始化连接池的参数,具体定义如下:


public class ConnectionParam implements Serializable
{
private String driver; //数据库驱动程序
private String url; //数据连接的URL
private String user; //数据库用户名
private String password; //数据库密码
private int minConnection = 0; //初始化连接数
private int maxConnection = 50; //最大连接数
private long timeoutValue = 600000;//连接的最大空闲时间
private long waitTime = 30000; //取连接的时候如果没有可用连接最大的等待时间




其次是连接池的工厂类ConnectionFactory,通过该类来将一个连接池对象与一个名称对应起来,使用者通过该名称就可以获取指定的连接池对象,具体代码如下:


/**
* 连接池类厂,该类常用来保存多个数据源名称合数据库连接池对应的哈希
* @author liusoft
*/
public class ConnectionFactory
{
//该哈希表用来保存数据源名和连接池对象的关系表
static Hashtable connectionPools = null;
static{
connectionPools = new Hashtable(2,0.75F);
}
/**
* 从连接池工厂中获取指定名称对应的连接池对象
* @param dataSource 连接池对象对应的名称
* @return DataSource 返回名称对应的连接池对象
* @throws NameNotFoundException 无法找到指定的连接池
*/
public static DataSource lookup(String dataSource)
throws NameNotFoundException
{
Object ds = null;
ds = connectionPools.get(dataSource);
if(ds == null || !(ds instanceof DataSource))
throw new NameNotFoundException(dataSource);
return (DataSource)ds;
}

/**
* 将指定的名字和数据库连接配置绑定在一起并初始化数据库连接池
* @param name 对应连接池的名称
* @param param 连接池的配置参数,具体请见类ConnectionParam
* @return DataSource 如果绑定成功后返回连接池对象
* @throws NameAlreadyBoundException 一定名字name已经绑定则抛出该异常

共4页: 上一页 1 [2] [3] [4] 下一页

上一篇:Weblogic下使用jsp查询的Entity Bean   下一篇:建立JSP操作用以提高数据库访问的效率


收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·建立JSP操作用以提高数据库访问的效率
·Weblogic下使用jsp查询的Entity Bean
·基础:从XML到Java代码的数据绑定之对象
·架构与模式:多线程有几种常用的编程模型
·Java程序开发过程中异常处理的特殊情况
·Servlet及JSP中遇到的多线程同步问题
·学习心得 - JSP处理异常及一些高级主题
·如何配置Java Server Page运行环境
·不要重新分配被锁定对象的对象引用
·JAVA入门基础:区分引用类型和原始类型
·Java理论和实践:用软引用阻止内存泄漏
·如何利用DES加密的算法保护Java源代码
·开发框架--Hibernate事务处理的机制
·开发JAVA编程中字符串分割的两种方法
·超线程多核心下Java多线程编程彻底分析
·设计及设计模式--设计模式之Factory
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·Java SE6调用Java编译器的两种新方法
·表现层框架Struts/Tapestry/JSF比较
·在Web项目中用到JNI时应该注意的问题
·JBuilder7 Weblogic7 mysql开发EJB配置
·进阶:Java Reflection (JAVA反射)详解
·以全局的固定顺序获取多个锁来避免死锁
·JAVA高级:Java中限时线程回调方式的实
·超线程多核心下Java多线程编程彻底分析
·开发JAVA编程中字符串分割的两种方法
·Java理论和实践:用软引用阻止内存泄漏
·JAVA入门基础:区分引用类型和原始类型
·学习心得 - JSP处理异常及一些高级主题
  阅读排行
·Commons-logging Log4j 的入门指南
·进阶:Java Reflection (JAVA反射)详解
·服务器及中间件:TomCat 多虚拟站点配置
·开发框架:一篇关于SSH架构的简单总结
·jboss4.0下使用MySql数据源的设置方法
·Java语言:敏捷开发技巧-消除代码异味
·Java SE6调用Java编译器的两种新方法
·架构与模式:多线程有几种常用的编程模
·数据库相关:Log4j和JDBMonitor的比较
·开发框架-Struts里过滤器的简单使用
·表现层框架Struts/Tapestry/JSF比较
·在Web项目中用到JNI时应该注意的问题
·设计模式之--Decorator模式、BUG和AOP
·开发框架--讨论Spring技巧之简洁配置
·Hibernate源码中几个包的作用简要介绍
网摘收藏: