📄 ch08.html
字号:
Connection Driver. </EM>The <EM CLASS="CODE">JDCConnectionDriver</EM><A NAME="marker-1087567"></A> class implements the <EM CLASS="CODE">java.sql.Driver</EM> interface, which provides methods to load drivers and create new database connections. A <EM CLASS="CODE">JDCConnectionDriver</EM><A NAME="marker-1087569"></A> object is created by the application seeking a database connection. The application provides the database URL for the database, login user ID, and login password. </P><P CLASS="Body"><A NAME="pgfId-1087570"></A>The <EM CLASS="CODE">JDCConnectionDriver</EM> constructor does the following: </P><UL><LI CLASS="BL"><A NAME="pgfId-1087571"></A>Registers the <EM CLASS="CODE">JDCConnectionDriver</EM> object with the <EM CLASS="CODE">DriverManager</EM></LI><LI CLASS="BL"><A NAME="pgfId-1087572"></A>Loads the <EM CLASS="CODE">Driver</EM> class passed to the constructor by the calling program</LI><LI CLASS="BL"><A NAME="pgfId-1087573"></A>Initializes a <EM CLASS="CODE">JDCConnectionPool</EM> object for the connections with the database URL, login user ID, and login password passed to the constructor by the calling program</LI></UL><P CLASS="Body"><A NAME="pgfId-1087574"></A>When the calling program needs a database connection, it calls the <EM CLASS="CODE">JDCConnectionDriver.connect</EM> method, which in turn, calls the <EM CLASS="CODE">JDCConnectionPool.getConnection</EM> method. </P><PRE CLASS="CODE"><A NAME="pgfId-1087577"></A><A NAME="marker-1087575"></A><A NAME="marker-1087576"></A>package pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087578"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087579"></A>import java.sql.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087580"></A>import java.util.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087581"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087582"></A>public class JDCConnectionDriver implements Driver {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087583"></A> public static final String URL_PREFIX = "jdbc:jdc:";</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087584"></A> private static final int MAJOR_VERSION = 1;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087585"></A> private static final int MINOR_VERSION = 0;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087586"></A> private JDCConnectionPool pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087587"></A> public JDCConnectionDriver(String driver, String url, String user, String password) </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087588"></A> throws ClassNotFoundException, </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087589"></A> InstantiationException, IllegalAccessException,</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087590"></A> SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087591"></A> DriverManager.registerDriver(this);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087592"></A> Class.forName(driver).newInstance();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087593"></A> pool = new JDCConnectionPool(url, user, password);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087594"></A>}</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087595"></A> public Connection connect(String url, Properties props) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087596"></A> if(!url.startsWith(URL_PREFIX) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087597"></A> return null;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087598"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087599"></A> return pool.getConnection();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087600"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087601"></A> public boolean acceptsURL(String url) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087602"></A> return url.startsWith(URL_PREFIX);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087603"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087604"></A> public int getMajorVersion() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087605"></A> return MAJOR_VERSION;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087606"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087607"></A> public int getMinorVersion() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087608"></A> return MINOR_VERSION;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087609"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087610"></A> public DriverPropertyInfo[] getPropertyInfo(String str, Properties props) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087611"></A> return new DriverPropertyInfo[0];</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087612"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087613"></A> public boolean jdbcCompliant() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087614"></A> return false;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087615"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087616"></A>}</PRE><P CLASS="Body"><A NAME="pgfId-1087618"></A><EM CLASS="Bold">Connection Pool. </EM>The <EM CLASS="CODE">JDCConnectionPool</EM><A NAME="marker-1087617"></A> class makes connections available to a calling program in its <EM CLASS="CODE">getConnection</EM><A NAME="marker-1087619"></A> method. This method searches for an available connection in the connection pool. If no connection is available from the pool, a new connection is created. If a connection is available from the pool, the <EM CLASS="CODE">getConnection</EM> method leases the connection and returns it to the calling program. </P><PRE CLASS="CODE"><A NAME="pgfId-1087622"></A><A NAME="marker-1087620"></A><A NAME="marker-1087621"></A>package pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087623"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087624"></A>import java.sql.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087625"></A>import java.util.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087626"></A>import java.io.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087627"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087628"></A>class ConnectionReaper extends Thread {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087629"></A> private JDCConnectionPool pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087630"></A> private final long delay=300000;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087631"></A> ConnectionReaper(JDCConnectionPool pool) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087632"></A> this.pool=pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087633"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087634"></A> public void run() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087635"></A> while(true) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087636"></A> try {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087637"></A> sleep(delay);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087638"></A> } catch( InterruptedException e) { }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087639"></A> pool.reapConnections();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087640"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087641"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087642"></A>}</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087643"></A>public class JDCConnectionPool {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087644"></A> private Vector connections;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087645"></A> private String url, user, password;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087646"></A> final private long timeout=60000;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087647"></A> private ConnectionReaper reaper;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087648"></A> final private int poolsize=10;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087649"></A> public JDCConnectionPool(String url, String user, String password) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087650"></A> this.url = url;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087651"></A> this.user = user;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087652"></A> this.password = password;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087653"></A> connections = new Vector(poolsize);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087654"></A> reaper = new ConnectionReaper(this);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087655"></A> reaper.start();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087656"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087657"></A> public synchronized void reapConnections() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087658"></A> long stale = System.currentTimeMillis() - timeout;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087659"></A> Enumeration connlist = connections.elements();</PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087661"></A>//API Ref: <A NAME="97708"></A>boolean hasMoreElements()</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087666"></A> <A NAME="methods"></A><A NAME="java.util.Enumeration class"></A><A NAME="Enumeration class"></A><A NAME="hasMoreElements method"></A>while((connlist != null) && (connlist.hasMoreElements())) {</PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087668"></A>//API Ref: <A NAME="34919"></A>Object nextElement()</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087671"></A> <A NAME="methods"></A><A NAME="nextElement method"></A>JDCConnection conn = (JDCConnection)connlist.nextElement();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087672"></A> if((conn.inUse()) && (stale >conn.getLastUse()) && (!conn.validate())) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087673"></A> removeConnection(conn);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087674"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087675"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087676"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087677"></A> public synchronized void closeConnections() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087678"></A> Enumeration connlist = connections.elements();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087679"></A> while((connlist != null) && (connlist.hasMoreElements())) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087680"></A> JDCConnection conn = (JDCConnection)connlist.nextElement();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087681"></A> removeConnection(conn);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087682"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087683"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087684"></A> private synchronized void removeConnection(JDCConnection conn) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087685"></A> connections.removeElement(conn);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087686"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087687"></A> public synchronized Connection getConnection() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087688"></A> JDCConnection c;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087689"></A> for(int i = 0; i < connections.size(); i++) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087690"></A> c = (JDCConnection)connections.elementAt(i);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087691"></A> if(c.lease()) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087692"></A> return c;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087693"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087694"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087695"></A> Connection conn = DriverManager.getConnection(url, user, password);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087696"></A> c = new JDCConnection(conn, this);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087697"></A> c.lease();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087698"></A> connections.addElement(c);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087699"></A> return c;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087700"></A> } </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087701"></A> public synchronized void returnConnection(JDCConnection conn) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087702"></A> conn.expireLease();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087703"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087704"></A>}</PRE><P CLASS="Body"><A NAME="pgfId-1087705"></A> </P><P CLASS="Body"><A NAME="pgfId-1087707"></A>The <A NAME="marker-1087706"></A>JDCConnection class represents a JDBC connection in the connection pool, and is essentially a wrapper around a real JDBC connection. The <EM CLASS="CODE">JDCConnection</EM> object maintains a state flag to indicate if the connection is in use and the time the connection was taken from the pool. This time is used by the <EM CLASS="CODE">ConnectionReaper</EM><A NAME="marker-1087708"></A> class to identify hanging connections.</P><PRE CLASS="CODE"><A NAME="pgfId-1087711"></A><A NAME="marker-1087709"></A><A NAME="marker-1087710"></A>package pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087712"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087713"></A>import java.sql.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087714"></A>import java.util.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087715"></A>import java.io.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087716"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087717"></A>public class JDCConnection implements Connection {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087718"></A> private JDCConnectionPool pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087719"></A> private Connection conn;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087720"></A> private boolean inuse;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087721"></A> private long timestamp;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087722"></A> public JDCConnection(Connection conn, JDCConnectionPool pool) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087723"></A> this.conn=conn;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087724"></A> this.pool=pool;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087725"></A> this.inuse=false;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087726"></A> this.timestamp=0;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087727"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087728"></A> public synchronized boolean lease() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087729"></A> if(inuse) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087730"></A> return false;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087731"></A> } else {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087732"></A> inuse=true;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087733"></A> timestamp=System.currentTimeMillis();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087734"></A> return true;</PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -