?原理: ???????? 在DataSource中事先建立多個數(shù)據(jù)庫連接,保存在數(shù)據(jù)庫連接池中。當程序訪問數(shù)據(jù)庫時,只用從連接池中取空閑狀態(tài)的數(shù)據(jù)庫連接即可,訪問結(jié)束,銷毀資源,數(shù)據(jù)庫連接重新回到連接池,這與每次去直接訪問數(shù)據(jù)庫相比,會節(jié)省大量時間和資源。 ???????? JNDI( Java Naming and Directory Interface ),是Java平臺的一個標準擴展,提供了一組接口、類和關(guān)于命名空間的概念。如同其它很多Java技術(shù)一樣,JDNI是provider-based的技術(shù),暴露了一個 API和一個服務供應接口(SPI)。這意味著任何基于名字的技術(shù)都能通過JNDI而提供服務,只要JNDI支持這項技術(shù)。JNDI目前所支持的技術(shù)包括 LDAP、CORBA Common Object Service(COS)名字服務、RMI、NDS、DNS、Windows注冊表等等。很多J2EE技術(shù),包括EJB都依靠JNDI來組織和定位實體。可以把它理解為一種將對象和名字捆綁的技術(shù),對象工廠負責生產(chǎn)出對象,這些對象都和唯一的名字綁在一起,外部資源可以通過名字獲得某對象的引用。
??? ?? ?? 在javax.naming的包包中提供Context接口,提供了兩個很好用的方法: <1> void bind( String name , Object object ) ??? ??? 將名稱綁定到對象。所有中間上下文和目標上下文(由該名稱最終原子組件以外的其他所有組件指定)都必須已經(jīng)存在。
<2>Object lookup( String name )
??? ??
檢索指定的對象。如果 name為空,則返回此上下文的一個新實例(該實例表示與此上下文相同的命名上下文,但其環(huán)境可以獨立地進行修改,而且可以并發(fā)訪問)。
??? ?? 外部資源訪問對象工廠中的工程圖:
例: =================將以下代碼段添加到server.xml中的<Host>中============
- <!-- configure DataSource. Add the following code into server.xml -->
<Context path="/bookstore" docBase="bookstore" debug="0" reloadable="true" >
<!-- 數(shù)據(jù)源名稱 --> <Resource name="jdbc/BookDB" ?????????????? auth="Container" ?????????????? type="javax.sql.DataSource" />
<ResourceParams name="jdbc/BookDB"> ??? <parameter> ????? <name>factory</name> ????? <value>org.apache.commons.dbcp.BasicDataSourceFactory</value> ??? </parameter>
??? <!-- Maximum number of dB connections in pool. Make sure you ???????? configure your mysqld max_connections large enough to handle ???????? all of your db connections. Set to 0 for no limit. ???????? -->
- <!-- 活動狀態(tài)最大連接數(shù) -->
??? <parameter> ????? <name>maxActive</name> ????? <value>100</value> ??? </parameter>
??? <!-- Maximum number of idle dB connections to retain in pool. ???????? Set to 0 for no limit. ???????? -->
- <!-- 空閑狀態(tài)數(shù)據(jù)庫連接最大數(shù) -->
??? <parameter> ????? <name>maxIdle</name> ????? <value>30</value> ??? </parameter>
??? <!-- Maximum time to wait for a dB connection to become available ???????? in ms, in this example 10 seconds. An Exception is thrown if ???????? this timeout is exceeded. Set to -1 to wait indefinitely. ??????? Maximum time to wait for a dB connection to become available ???????? in ms, in this example 10 seconds. An Exception is thrown if ???????? this timeout is exceeded. Set to -1 to wait indefinitely. ???????? -->
- <!-- 數(shù)據(jù)庫處于空閑狀態(tài)的最長時間 -->
??? <parameter> ????? <name>maxWait</name> ????? <value>10000</value> ??? </parameter>
??? <!-- MySQL dB username and password for dB connections -->
- <!-- 指定連接數(shù)據(jù)庫的用戶名及密碼 -->
??? <parameter> ???? <name>username</name> ???? <value>dbuser</value> ??? </parameter> ??? <parameter> ???? <name>password</name> ???? <value>1234</value> ??? </parameter>
??? <!-- Class name for mm.mysql JDBC driver -->
- <!-- 指定JDBC驅(qū)動 -->
??? <parameter> ?????? <name>driverClassName</name> ?????? <value>com.mysql.jdbc.Driver</value> ??? </parameter>
??? <!-- The JDBC connection url for connecting to your MySQL dB. ???????? The autoReconnect=true argument to the url makes sure that the ???????? mm.mysql JDBC Driver will automatically reconnect if mysqld closed the ???????? connection. mysqld by default closes idle connections after 8 hours. ???????? -->
- <!-- 指定連接數(shù)據(jù)庫的URL -->
??? <parameter> ????? <name>url</name> ????? <value>jdbc:mysql://localhost:3306/BookDB?autoReconnect=true</value> ??? </parameter> </ResourceParams>
</Context>
|
運行機制:
????
1、
首先程序代碼獲取初始化的
JNDI
環(huán)境并且調(diào)用
Context.lookup()
方法從
JNDI
服務提供者那里獲一個
DataSource
對象
????
2、
中間層
JNDI
服務提供者返回一個
DataSource
對象給當前的
Java
應用程序這個
DataSource
對象代表了中間層服務上現(xiàn)存的緩沖數(shù)據(jù)源
??????3、
應用程序調(diào)用
DataSource
對象的
getConnection()
方法
????
4、
當
DataSource
對象的
getConnection()
方法被調(diào)用時,中間層服務器將查詢數(shù)據(jù)庫
連接緩沖池中有沒有
PooledConnection
接口的實例對象。這個
PooledConnection
對象將被用于與數(shù)據(jù)庫建立物理上的數(shù)據(jù)庫連接
????
5、
如果在緩沖池中命中了一個
PooledCoonection
對象那么連接緩沖池將簡單地更
新內(nèi)部的緩沖連接隊列并將該
PooledConnection
對象返回。如果在緩沖池內(nèi)沒
有找到現(xiàn)成的
PooledConnection
對象,那么
ConnectionPoolDataSource
接口將會被
用來產(chǎn)生一個新的
PooledConnection
對象并將它返回以便應用程序使用
????
6。
中間層服務器調(diào)用
PooledConnection
對象的
getConnection()
方法以便返還一個
java.sql.Connection
對象給當前的
Java
應用程序
????
7、
當中間層服務器調(diào)用
PooledConnection
對象的
getConnection()
方法時,
JDBC
數(shù)據(jù)
庫驅(qū)動程序?qū)?chuàng)建一個
Connection
對象并且把它返回中間層服務器
????
8、
中間層服務器將
Connection
對象返回給應用程序
Java
應用程序,可以認為這個
Connection
對象是一個普通的
JDBC Connection
對象使用它可以和數(shù)據(jù)庫建立。事
實上的連接與數(shù)據(jù)庫引擎產(chǎn)生交互操作 。
????
9、
當應用程序不需要使用
Connection
對象時,可以調(diào)用
Connection
接口的
close()
方
法。請注意這種情況下
close()
方法并沒有關(guān)閉事實上的數(shù)據(jù)庫連接,僅僅是釋
放了被應用程序占用的數(shù)據(jù)庫連接,并將它還給數(shù)據(jù)庫連接緩沖池,數(shù)據(jù)庫連接
緩沖池會自動將這個數(shù)據(jù)庫連接交給請求隊列中下一個的應用程序使用。