在JDBC20或JDBC30中,所有的数据库驱动程序提供商必须提供一个实现了DataSource接口的类,要使用数据源必须首先在JNDI中注册该数据源对象。
如果在JNDI中注册了数据源对象,将会比起使用DriverManager来具有两个方面的优势:
首先,程序不需要像使用DriverManager一样对加载的数据库驱动程序信息进行硬编码,程序员可以选择先在JNDI中注册这个数据源对象,然后在 程序中使用一个逻辑名称来引用它,JNDI会自动根据你给出的名称找到与这个名称绑定的DataSource对象。然后就可以使用这个 DataSource对象来建立和具体数据库的连接了。
其次,使用实现了DataSource接口的类所具有的第二个优势体现在连接池和分布式事务上。连接池通过对连接的复用而不是新建一个物理连接来显著地提高程序的效率。从而适用于任务繁忙、负担繁重的企业级分布式事务。
数据库连接池的基本原理
传统的数据库连接方式(指通过DriverManager和基本实现DataSource进行连接)中,一个数据库连接对象均对应一个物理数据库连接,数 据库连接的建立以及关闭对系统而言是耗费系统资源的 *** 作,在多层结构的应用程序环境中这种耗费资源的动作对系统的性能影响尤为明显。
在多层结构的应用程序中通过连接池(connection pooling)技术可以使系统的性能明显得到提到,连接池意味着当应用程序需要调用一个数据库连接的时,数据库相关的接口通过返回一个通过重用数据库连 接来代替重新创建一个数据库连接。通过这种方式,应用程序可以减少对数据库连接 *** 作,尤其在多层环境中多个客户端可以通过共享少量的物理数据库连接来满足 系统需求。通过连接池技术Java应用程序不仅可以提高系统性能同时也为系统提高了可测量性。
数据库连接池是运行在后台的而且应用程序的编码没有任何的影响。此中状况存在的前提是应用程序必须通过DataSource对象(一个实现 javaxsqlDataSource接口的实例)的方式代替原有通过DriverManager类来获得数据库连接的方式。一个实现 javaxsqlDataSource接口的类可以支持也可以不支持数据库连接池,但是两者获得数据库连接的代码基本是相同的。
一个DataSource对象通常注册在JNDI命名服务上,应用程序可以通过标准的方式获得到注册在JNDI服务上的DataSource对象。 代码如下:
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctxlookup("jdbc/openbase");
如果当前DataSource不支持数据库连接池,应用程序将获得一个和物理数据库连接对应的Connection对象。而如果当前的 DataSource对象支持数据库连接池,应用程序自动获得重用的数据库连接而不用创建新的数据库连接。重用的数据库连接和新建立连接的数据库连接使用 上没有任何不同。应用程序可以通过重用的连接正常的访问数据库,进行访问数据的 *** 作,完成 *** 作后应显式的调用close()关闭数据库连接。
Connection con = dsgetConnection("User", "Pwd");
相关数据库的 *** 作;
conclose();
当关闭数据连接后,当前使用的数据库连接将不会被物理关闭,而是放回到数据库连接池中进行重用。
JDBC30规范中数据库连接池框架
JDBC30规范中通过提供了一个支持数据库连接池的框架,这个框架仅仅规定了如何支持连接池的实现,而连接池的具体实现JDBC 30规范并没有做相关的规定。通过这个框架可以让不同角色的开发人员共同实现数据库连接池。
通过JDBC30规范可以知道具体数据库连接池的实现可以分为JDBC Driver级和Application Server级。在JDBC Driver级的实现中任何相关的工作均由特定数据库厂商的JDBC Drvier的开发人员来具体实现,即JDBC Driver既需要提供对数据库连接池的支持同时也必须对数据库连接池进行具体实现。而在Application Server级中数据库连接池的实现中特定数据库厂商的JDBC Driver开发人员和Application Server开发人员来共同实现数据库连接池的实现(但是现在大多数Application Server厂商实现的连接池的机制和规范中提到有差异),其中特定数据库厂商的JDBC Driver提供数据库连接池的支持而特定的Application Server厂商提供数据库连接池的具体实现。
JDBC30规范规定了如下的类和接口来支持数据库连接池的实现。
javaxsqlConnectionEvent
javaxsqlConnectionPoolDataSource
javaxsqlPooledConnection
javaxsqlConnectionEventListener
其中除javaxsqlConnectionEvent是类,其它的均为接口。
C:/1jpg
screenwidth-333)thiswidth=screenwidth-333;" src="/Develop/ArticleImages/19/19446/CSDN_Dev_Image_2003-7-41948411jpg">
JDBC30连接池框架的关系图
通过此图可以大概的了解相关接口在一个典型的三层环境中应用程序的位置。
数据库连接池实现层次中,由特定数据库厂商的JDBC Driver开发人员提供连接池支持,而特定Application Server提供连接池实现的情况比较复杂,其它的实现层次均可视为其简化情况的一种。下面将针对这种情况进行说明。
在这个框架主要有两个用户角色存在,它们分别是:
特定数据库厂商的JDBC Driver开发人员,之后将简称为Driver Vendor
特定Application Server中连接池开发人员,之后将简称为Pooling Vendor
C:/2bmp
screenwidth-333)thiswidth=screenwidth-333;" src="/Develop/ArticleImages/19/19446/CSDN_Dev_Image_2003-7-41948413gif">
JDBC30规范中在上述情况下各个接口和类之间的UML图
下面对几个关键模块进行详细的说明:
Driver Vendor DataSource:
Driver Vendor必须提供一个ConnectionPoolDataSource 接口的具体实现,通过这个接口Pooling Vendor可以得到一个PooledConnection对象,从而使第三方实现的连接池可以使用特定数据库厂商得到JDBC Driver产生的数据库连接。在这里ConnectionPoolDataSource接口扮演的角色可以视为产生PooledConnection 对象的工厂。
Driver Vendor PooledConnection:
Driver Vendor必须提供标准PooledConnection 接口实现的类,这个接口允许Pooling Vendor在JDBC Driver提供连接池支持的基础上实现连接池。一个具体PooledConnection对象代表了一个物理的数据库连接;由 PooledConnection对象创建Connection对象仅仅只是一个指向PooledConnetion对象的句柄。在JDBC 30连接池实现框架中PooledConnection对象扮演的角色可以视为产生Connection对象的工厂。
Pooling Vendor DataSource:
Pooling Vendor必须实现DataSource接口,这个接口是和连接池实现模块进行交互的入口点。ConnectionPoolDataSource根据需要创建PooledConnection对象。
Pooling Vendor Connection Cache:
此模块是Pooling Vendor对连接池的具体实现。JDBC 30 规范没有规定在DataSource对象和数据库连接池实现之间的需要实现的接口,所以它们之间的交互由Pooling Vendor自己定义。一般而言,一个数据库连接池的具体实现包含了一个或若干个具体的类,但是在连接池实现模块中必须包含一个类实现标准 ConnectionEventListener接口。当一个PooledConnectiond对象被关闭或者出现异常的时 候,PooledConnection对象将会向ConnectionEventListener接口发送ConnectionEvent对象,连接池实 现模块将会根据返回的ConnectionEvent对象对PooledConnection进行关闭或者重用 *** 作。
ConnectionEvent:
实现连接池时,当应用程序调用Connectionclose()试图去关闭数据库连接时,这时需要有一个通告给连接池实现模块,通告对当前的数据 库物理连接(PooledConnection 对象)进行重用。为了使连接池实现模块能得到这种"通告",连接池实现模块必须实现ConnectionEventListener接口,而且同时需要注 册成为PooledConnection对象的监听者。连接池实现模块通过 PooledConnectionaddConnectionEventListener()方法注册自己成为一个监听者。
在典型三层环境中具体调用流程:
当应用程序通过调用DataSourcegetConnection()得到一个数据库连接。
Pooling Vendor实现的DataSource对象在连接池中进行查找看当前是否有有效的PooledConnection对象,如果连接池中有可用的PooledConnection,则进行检查,如果当前的PooledConnection可用则使用。
如果如果连接池中没有可用的PooledConnection对象,或者当前的PooledConnection对象不正确,那么Pooling Vendor调用ConnectionPoolDataSourcegetPooledConnection类创建一个新的 PooledConnection对象,这时由Driver Vendor实现的ConnectionPoolDataSource将会创建一个满足要求新的PooledConnection对象,并将其返回给连接 池实现模块进行管理。
然后,Pooling Vendor会调用PooledConnectiongetConnection()获得一个逻辑的Connection对象,这个逻辑的 Connection对象将会象正常的Connection对象返回给应用程序。这个逻辑Connection对象实际上是连接池中 PooledConnection对象的一个句柄,当连接池有效时,应用程序调用DataSourcegetConnection()就会得到这个句 柄。简而言之,应用程序此时使用的Connection对象仅仅是其创建者PooledConnection对象的句柄而已。
连接池实现模块调用PooledConnectionaddConnectionEventListener()将自己注册成为一个PooledConnection对象的监听者,当数据库连接需要重用或者关闭的时候连接池实现模块可以得到通告。
当应用程序通过调用Connectionclose()来关闭数据库连接,这时一个ConnectionEvent对象被创建并被返回到连接池实现 模块,连接池实现模块接受到此通告后,将PooledConnection对象返回到池中进行重用。这些过程中其它角色都不能访问 PooledConnectionclose()方法,能访问这个方法的只有Pooling Vendor,它们使用这个方法对连接池中的对象进行 *** 作,通过PooledConnectionclose()方法可以关闭物理数据库连接。
tomcat连接池的方法
1:连接池所要解决的问题:
应用程序每一次与数据库的连接都会由于网络传输和执行数据库查询而严重降低了程序的执行效率,因此我们需要用到连接池将将我们经常要用到的数据保存在连接池中,这样就减少了网络传输和因查询而给程序执行效率带来的影响。
2:连接池的本质:用一个集合保存查询出来的数据。
3:连接池的实现原理:
我们要使用Connect pool,首先要做的是访问datasource(所有的要访问的数据都放在这里面)。datasource数据源是通过LDAP(light directory access protocal)软件进行管理的(其本质就是将数据源以树状结构进行存储,这样的话,方便查询(树状结构的查询效率是最快的),java通过JNDI(java naming directory interface)访问LDAP里面的数据。
4:在tomcat种配置连接池:
1)打开tomcat目录下的conf/contextcfg:在里面加入如下配置
Xml代码
<Resource driverClassName="oraclejdbcdriverOracleDriver"url="jdbc:oracle:thin:@localhost:1521:orcl" username="scott" password="tiger" maxActive="20" type="javaxsqlDataSource" author="Container" name="ds"></Resource>
<Resource driverClassName="oraclejdbcdriverOracleDriver"url="jdbc:oracle:thin:@localhost:1521:orcl" username="scott" password="tiger" maxActive="20" type="javaxsqlDataSource" author="Container" name="ds"></Resource>
其中:maxActive:代表的是要配置的最大连接数。
type:资源类型
2)通过应用程序执行上述连接:
Java代码
<%@page contentType="text/html" %>
<%@page import="javasql"%>
<%@page import="javaxsql"%>
<%@page import="javaxnaming"%>
<html>
<body>
<% Context ctx=new InitialContext();
DataSource ds=(DataSource)ctxlookup("java:comp/env/ds");//必须要
Connection con=dsgetConnection();
outprintln("<h1>connection succeeful</h1>");
conclose();
%>
</body>
</html>
<%@page contentType="text/html" %>
<%@page import="javasql"%>
<%@page import="javaxsql"%>
<%@page import="javaxnaming"%>
<html>
<body>
<% Context ctx=new InitialContext();
DataSource ds=(DataSource)ctxlookup("java:comp/env/ds");//必须要
Connection con=dsgetConnection();
outprintln("<h1>connection succeeful</h1>");
conclose();
%>
</body>
</html>
connclose():连接池是被覆盖了的,本质上的含义,把连接池借过来的连接还回去。
从零开始学java web 开发书上的例子
以sql server 2005为例,讲解tomcat60上的配置。
下载sqljdbcjar放在tomcat的lib目录,tomcat/conf/contextxml文件,<Context></Context>中加入配置代码。
<Resource name="jdbc/dbplling" author="Container" type="javaxsqlDataSource" driverClassName="commicrosoftsqlserverdriverjdbcsqlserverdriverDriver"url="jdbc:sqlserver//127001:1433;databasename=testdemo" username="sa" password="123" maxActive="100" maxIdle="30"; maxWait="5000"></Resource>
webxml
<xml version="10" encoding="UTF-8">
<web-app version="24" xmlns=">
像打开关闭数据库连接这种和数据库的交互可能是很费时的,尤其是当客户端数量增加的时候,会消耗大量的资源,成本是非常高的。可以在应用服务器启动的时候建立很多个数据库连接并维护在一个池中。连接请求由池中的连接提供。在连接使用完毕以后,把连接归还到池中,以用于满足将来更多的请求。
连接池是被j2ee服务器打开和维护的
对应1、2、4的JDBC驱动程序
连接池一般比直接连接更有优越性
因为它提高了性能的同时还保存了
宝贵的资源。
打开数据库连接时CPU和网络的重要
任务,因此,在整个应用程序的使用过程
当中重复的打开直接连接将导致性能的下降。
而池连接只在服务器启动时打开一次,从而
消除了这种性能问题。
另外,因为连接只用于很短的时间,
所以,连接可以被有效共享,
而且有关连接参数的特有信息,
只对池驱动程序有效,
如数据库用户名称和密码,
从而增强了系统的安全性和可管理性。
ps:(以上文字摘抄网上老鸟的,嘿嘿描述太多就懒得写了,我还是总结实现原理在这就树下乘凉了哈哈!!!)
就是在连接池初始化的时候存入一定数量的连接,用的时候通过方法获取,不用的时候归还连接即可
所有的连接池必须实现一个接口 javaxsqlDataSource接口
查看api:(DataSource)
获取连接方法:
Connection getConnection()
我们发现只有连接的方法 没有归还的方法归还连接的方法就是以前的释放资源的方法调用connectionclose();
小结: 终于又总结完了一张,通过本篇掌握jdbc连接池相关的作用及其思想,以及装饰者模式就行。
参考:dbcp c3p0其dbutils总结
以上就是关于用DriverManager和DataSource获得Connection的区别在哪全部的内容,包括:用DriverManager和DataSource获得Connection的区别在哪、java 因为数据库反复的连接是很耗资源的,所以用连接池比较好、数据库连接池是什么意思等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)