﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-study-随笔分类-JDBC</title><link>http://www.blogjava.net/xixidabao/category/15376.html</link><description>GROW WITH JAVA</description><language>zh-cn</language><lastBuildDate>Fri, 24 Aug 2007 09:13:35 GMT</lastBuildDate><pubDate>Fri, 24 Aug 2007 09:13:35 GMT</pubDate><ttl>60</ttl><item><title>如何在oracle使用blob,clob</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/22/138584.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 22 Aug 2007 05:05:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/22/138584.html</guid><description><![CDATA[<span id=Label4>转:http://blog.tostudy.com.cn/blog/show_930.html&nbsp;
<p><br>一.写入BLOB</p>
<p>1.先在blob中插入empty_blob()<br>2.获得对刚刚插入记录的引用<br>BLOB blob = (BLOB) rs.getBlob("你的blob字段名称");<br>3.写入<br>OutputStream out = blob.getBinaryOutputStream();<br>out.write(ENCYPWD);//注意这里<br>二.读出BLOB</p>
<p>1.blob&nbsp; = rs.getBlob("你的blob字段名称");<br>2.<br>InputStream is = blob.getBinaryStream();<br>int length = (int) blob.length();<br>byte[] buffer = new byte[length];<br>is.read(buffer);<br>is.close();<br>3.你有了is就随便处理了<br>比如说输出到一个文件<br>FileOutputStream fo = new FileOutputStream(filename);//数据到的文件名<br>fo.write(buffer);<br>fo.close();</p>
环境：<br>Database: Oracle 9i<br>App Server: BEA Weblogic 8.14<br></strong>表结构：<br>CREATE TABLE TESTBLOB (ID Int, NAME Varchar2(20), BLOBATTR Blob)<br>CREATE TABLE TESTBLOB (ID Int, NAME Varchar2(20), CLOBATTR Clob)</strong> &nbsp; JAVA可以通过JDBC，也可以通过JNDI访问并操作数据库，这两种方式的具体操作存在着一些差异，由于通过App Server的数据库连接池JNDI获得的数据库连接提供的java.sql.Blob和java.sql.Clob实现类与JDBC方式提供的不同，因此在入库操作的时候需要分别对待；出库操作没有这种差异，因此不用单独对待。 <br>一、BLOB操作<br>1、入库<br>（1）JDBC方式<br>&nbsp;&nbsp;&nbsp; //通过JDBC获得数据库连接<br>&nbsp;&nbsp;&nbsp; Class.forName("oracle.jdbc.driver.OracleDriver");<br>&nbsp;&nbsp;&nbsp; Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_blob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Blob对象后强制转换为oracle.sql.BLOB<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outStream = blob.getBinaryOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的byte数组，定义：byte[] data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(data, 0, data.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> （2）JNDI方式<br>&nbsp;&nbsp;&nbsp; //通过JNDI获得数据库连接<br>&nbsp;&nbsp;&nbsp; Context context = new InitialContext();<br>&nbsp;&nbsp;&nbsp; ds = (DataSource) context.lookup("ORA_JNDI");<br>&nbsp;&nbsp;&nbsp; Connection con = ds.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_blob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Blob对象后强制转换为weblogic.jdbc.vendor.oracle.OracleThinBlob（不同的App Server对应的可能会不同）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weblogic.jdbc.vendor.oracle.OracleThinBlob blob = (weblogic.jdbc.vendor.oracle.OracleThinBlob) rs.getBlob("BLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outStream = blob.getBinaryOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的byte数组，定义：byte[] data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(data, 0, data.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> 2、出库<br>&nbsp;&nbsp;&nbsp; //获得数据库连接<br>&nbsp;&nbsp;&nbsp; Connection con = ConnectionFactory.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //不需要&#8220;for update&#8221;<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Blob blob = rs.getBlob("BLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream inStream = blob.getBinaryStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是读出并需要返回的数据，类型是byte[]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new byte[input.available()];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.read(data);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> &nbsp; 二、CLOB操作<br>1、入库<br>（1）JDBC方式<br>&nbsp;&nbsp;&nbsp; //通过JDBC获得数据库连接<br>&nbsp;&nbsp;&nbsp; Class.forName("oracle.jdbc.driver.OracleDriver");<br>&nbsp;&nbsp;&nbsp; Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_clob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Clob对象后强制转换为oracle.sql.CLOB<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writer outStream = clob.getCharacterOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的字符串，定义：String data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] c = data.toCharArray();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(c, 0, c.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();<br></strong>（2）JNDI方式<br>&nbsp;&nbsp;&nbsp; //通过JNDI获得数据库连接<br>&nbsp;&nbsp;&nbsp; Context context = new InitialContext();<br>&nbsp;&nbsp;&nbsp; ds = (DataSource) context.lookup("ORA_JNDI");<br>&nbsp;&nbsp;&nbsp; Connection con = ds.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_clob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Clob对象后强制转换为weblogic.jdbc.vendor.oracle.OracleThinClob（不同的App Server对应的可能会不同）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weblogic.jdbc.vendor.oracle.OracleThinClob clob = (weblogic.jdbc.vendor.oracle.OracleThinClob) rs.getClob("CLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writer outStream = clob.getCharacterOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的字符串，定义：String data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] c = data.toCharArray();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(c, 0, c.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> 2、出库<br>&nbsp;&nbsp;&nbsp; //获得数据库连接<br>&nbsp;&nbsp;&nbsp; Connection con = ConnectionFactory.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //不需要&#8220;for update&#8221;<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Clob clob = rs.getClob("CLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reader inStream = clob.getCharacterStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] c = new char[(int) clob.length()];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.read(c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是读出并需要返回的数据，类型是String<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new String(c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> &nbsp; 需要注意的地方：<br>1、java.sql.Blob、oracle.sql.BLOB、weblogic.jdbc.vendor.oracle.OracleThinBlob几种类型的区别<br>2、java.sql.Clob、oracle.sql.CLOB、weblogic.jdbc.vendor.oracle.OracleThinClob几种类型的区别</strong> </span>
<img src ="http://www.blogjava.net/xixidabao/aggbug/138584.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-22 13:05 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/22/138584.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet开发中JDBC的高级应用</title><link>http://www.blogjava.net/xixidabao/archive/2006/05/21/47390.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Sun, 21 May 2006 15:47:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2006/05/21/47390.html</guid><description><![CDATA[
		<b>连结数据库</b>
		<br />
		<br />　　<a class="bluekey" href="http://www.yesky.com/key/3257/8257.html" target="_blank">JDBC</a>使用数据库<a class="bluekey" href="http://www.yesky.com/key/736/100736.html" target="_blank">URL</a>来说明<a class="bluekey" href="http://www.yesky.com/key/4703/239703.html" target="_blank">数据库驱动程序</a>。数据库URL类似于<a class="bluekey" href="http://www.yesky.com/key/1542/56542.html" target="_blank">通用</a>的URL，但SUN 在定义时作了一点简化，其<a class="bluekey" href="http://www.yesky.com/key/961/45961.html" target="_blank">语法</a>如下： <br /><br />　　<a class="bluekey" href="http://www.yesky.com/key/666/160666.html" target="_blank">Jdbc:</a>:[node]/[<a class="bluekey" href="http://www.yesky.com/key/4217/124217.html" target="_blank">database</a>] <br /><br />　　其中子协议（subprotocal）定义<a class="bluekey" href="http://www.yesky.com/key/321/321.html" target="_blank">驱动</a>程序类型，node提供网络数据库的位置和端口号，后面跟可选的参数。例如： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><a class="bluekey" href="http://www.yesky.com/key/2462/102462.html" target="_blank">String</a> url=”jdbc:inetdae:myser<a class="bluekey" href="http://www.yesky.com/key/4310/99310.html" target="_blank">ver:1</a>433<a class="bluekey" href="http://www.yesky.com/key/2504/182504.html" target="_blank">?l</a>anguage=us-<a class="bluekey" href="http://www.yesky.com/key/1804/121804.html" target="_blank">english</a>&amp;sql7=<a class="bluekey" href="http://www.yesky.com/key/1169/101169.html" target="_blank">true</a>” </td></tr></tbody></table><br />　　表示采用inetdae驱动程序连接<a class="bluekey" href="http://www.yesky.com/key/3479/133479.html" target="_blank">1433</a>端口上的my<a class="bluekey" href="http://www.yesky.com/key/4507/279507.html" target="_blank">server数据库</a>服务器，选择<a class="bluekey" href="http://www.yesky.com/key/953/45953.html" target="_blank">语言</a>为美国英语，数据库的版本是ms<a class="bluekey" href="http://www.yesky.com/key/1929/216929.html" target="_blank">sql server</a> 7.0。 <br /><br />　　<a class="bluekey" href="http://www.yesky.com/key/412/135412.html" target="_blank">java</a>应用通过指定DriverManager装入一个驱动程序类。语法如下： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>Class.forName(“”);</td></tr></tbody></table><br />　　或 　<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>Class.forName(“”).newInstance(); </td></tr></tbody></table><br />　　然后，DriverManager创建一个特定的连接： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><a class="bluekey" href="http://www.yesky.com/key/1551/261551.html" target="_blank">Connection</a> connection=DriverManager.getConnection(url,<a class="bluekey" href="http://www.yesky.com/key/832/160832.html" target="_blank">login</a>,<a class="bluekey" href="http://www.yesky.com/key/4197/109197.html" target="_blank">password</a>)； </td></tr></tbody></table><br />　　Connection<a class="bluekey" href="http://www.yesky.com/key/2969/77969.html" target="_blank">接口</a>通过指定数据库位置，登录名和密码<a class="bluekey" href="http://www.yesky.com/key/3966/73966.html" target="_blank">连接数据库</a>。Connection接口创建一个Statement实例<a class="bluekey" href="http://www.yesky.com/key/4175/44175.html" target="_blank">执行</a>需要的查询： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>Statement stmt=connection.createStatement(); </td></tr></tbody></table><br />　　Statement具有各种方法（<a class="bluekey" href="http://www.yesky.com/key/1434/161434.html" target="_blank">API</a>），如executeQuery，<a class="bluekey" href="http://www.yesky.com/key/2481/212481.html" target="_blank">execute</a>等可以返回查询的结果集。结果集是一个<a class="bluekey" href="http://www.yesky.com/key/4807/134807.html" target="_blank">ResultSet</a>对象。具体的可以通过jdbc开发文档<a class="bluekey" href="http://www.yesky.com/key/863/90863.html" target="_blank">查看</a>。可以sun的站点上下载 <br /><br />　　下面例子来说明： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><a class="bluekey" href="http://www.yesky.com/key/1897/116897.html" target="_blank">import</a><a class="bluekey" href="http://www.yesky.com/key/934/934.html" target="_blank">java</a>.sql.*; // 输入JDBC <a class="bluekey" href="http://www.yesky.com/key/4377/109377.html" target="_blank">package</a><br /><br />String url = "jdbc:inetdae:myserver:1433";// <a class="bluekey" href="http://www.yesky.com/key/3987/203987.html" target="_blank">主机名</a>和端口 <br />String login = "<a class="bluekey" href="http://www.yesky.com/key/446/100446.html" target="_blank">user</a>";// 登录名 <br />String password = "";// 密码 <br /><br />try { <br />　　DriverManager.setLogStream(System.out); <a class="bluekey" href="http://www.yesky.com/key/2652/162652.html" target="_blank">file</a>://为显示一些的信息打开一个流 <br />　　file://<a class="bluekey" href="http://www.yesky.com/key/1698/86698.html" target="_blank">调用</a>驱动程序，其名字为<a class="bluekey" href="http://www.yesky.com/key/2724/147724.html" target="_blank">com</a>.<a class="bluekey" href="http://www.yesky.com/key/2421/152421.html" target="_blank">inet</a>.tds.TdsDriver <br />　　file://Class.forName("<a class="bluekey" href="http://www.yesky.com/key/993/20993.html" target="_blank">com</a>.<a class="bluekey" href="http://www.yesky.com/key/1376/211376.html" target="_blank">inet</a>.tds.TdsDriver")； <br />　　file://设置<a class="bluekey" href="http://www.yesky.com/key/401/90401.html" target="_blank">超时</a><br />　　DriverManager.setLoginTimeout(10); <br />　　file://打开一个连接 <br />　　Connection connection = DriverManager.getConnection(url,login,password); <br />　　file://得到数据库驱动程序版本 <br /><br />　　　DatabaseMetaData conMD = connection.getMetaData(); <br />　　　System.out.println("<a class="bluekey" href="http://www.yesky.com/key/4965/159965.html" target="_blank">Driver</a><a class="bluekey" href="http://www.yesky.com/key/99/160099.html" target="_blank">Name</a>:\t" + conMD.getDriverName()); <br />　　　System.out.println("<a class="bluekey" href="http://www.yesky.com/key/3834/38834.html" target="_blank">Driver</a><a class="bluekey" href="http://www.yesky.com/key/1064/136064.html" target="_blank">Version</a>:\t" + conMD.getDriverVersion()); <br /><br />　　file://选择数据库 <br />　　connection.setCatalog( "MyDatabase"); <br /><br />　　file://创建Statement <br /><br />　　Statement <a class="bluekey" href="http://www.yesky.com/key/2568/102568.html" target="_blank">st</a> = connection.createStatement(); <br /><br />　　file://执行查询 <br /><br />　　ResultSet rs = st.executeQuery("<a class="bluekey" href="http://www.yesky.com/key/1601/161601.html" target="_blank">SELECT</a> * FROM mytable"); <br /><br />　　file://取得结果，输出到屏幕 <br /><br />　　while (rs.next()){ <br />　　　　　<a class="bluekey" href="http://www.yesky.com/key/3246/38246.html" target="_blank">for</a>(<a class="bluekey" href="http://www.yesky.com/key/1772/116772.html" target="_blank">int</a> j=1; j&lt;=rs.getMetaData().getColumnCount(); j++){ <br />　　　　　　System.out.<a class="bluekey" href="http://www.yesky.com/key/3451/13451.html" target="_blank">print</a>( rs.getObject(j)+"\t"); <br />　　　　　} <br />　　　System.out.println(); <br />　　} <br /><br />　　file://关闭对象 <br />　　st.close(); <br />　　　　connection.close(); <br />　　} catch(<a class="bluekey" href="http://www.yesky.com/key/1068/121068.html" target="_blank">Exception</a> e) { <br />　　　　e.printStackTrace(); <br />　　} </td></tr></tbody></table><br /><br /><br /><b>建立连结池</b><br /><br />　　一个动态的网站频繁地从数据库中取得数据来构成html页面。每一次请求一个页面都会发生数据库操作。但连接数据库却是一个需要消耗大量时间的工作，因为请求连接需要建立通讯，分配资源，进行权限认证。这些工作很少能在一两秒内完成。所以，建立一个连接，然后再后续的查询中都使用此连接会大大地提高性能。因为servlet可以在不同的请求间保持状态，因此采用数据库连接池是一个直接的解决方案。 <br /><br />　　Servlet在服务器的进程空间中驻留，可以方便而持久地维护数据库连接。接下来，我们介绍一个完整的连接池的实现。在实现中，有一个连接池管理器管理连接池对象，其中每一个连接池保持一组数据库连接对象，这些对象可为任何servlet所使用。 <br /><br />　　一、数据库连接池类 DBConnectionPool,提供如下的方法： <br /><br />　　1、从池中取得一个打开的连接； <br /><br />　　2、将一个连接返回池中； <br /><br />　　3、在关闭时释放所有的资源，并关闭所有的连接。 <br /><br />　　另外，DBConnectionPool还处理连接失败，比如超时，通讯失败等错误，并且根据预定义的参数限制池中的连接数。 <br /><br />　　二、管理者类，DBConnetionManager，是一个容器将连接池封装在内，并管理所有的连接池。它的方法有： <br /><br />　　1、 调用和注册所有的jdbc驱动程序； <br /><br />　　2、 根据参数表创建DBConnectionPool对象； <br /><br />　　3、 映射连接池的名字和DBConnectionPool实例； <br /><br />　　4、 当所有的连接客户退出后，关闭全部连接池。 <br /><br />　　这些类的实现，以及如何在servlet中使用连接池的应用在随后的文章中讲解 <br /><br />　　DBConnectionPool类代表一个由url标识的数据库连接池。前面，我们已经提到，jdbc的url由三个部分组成：协议标识（总是jdbc）,子协议标识（例如，odbc.oracle）,和数据库标识（跟特定的数据库有关）。连接池也具有一个名字，供客户程序引用。另外，连接池还有一个用户名，一个密码和一个最大允许连接数。如果web应用允许所有的用户使用某些数据库操作，而另一些操作是有限制的，则可以创建两个连接池，具有同样的url,不同的user name和password，分别处理两类不同的操作权限。现把DBConnectionPool详细介绍如下： <br /><br />　　三、DBConnectionPool的构造 <br /><br />　　构造函数取得上述的所有参数： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public DBConnectionPool(String name, String URL, String user, <br />String password, int maxConn) { <br />　this.name = name; <br />　this.URL = URL; <br />　this.user = user; <br />　this.password = password; <br />　this.maxConn = maxConn; <br />} </td></tr></tbody></table><br />　　将所有的参数保存在实例变量中。 <br /><br />　　四、从池中打开一个连接 <br /><br />　　DBConnectionPool提供两种方法来检查连接。两种方法都返回一个可用的连接，如果没有多余的连接，则创建一个新的连接。如果最大连接数已经达到，第一个方法返回null，第二个方法则等待一个连接被其他进程释放。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public synchronized Connection getConnection() { <br />　Connection con = null; <br />　if (freeConnections.size() &gt; 0) { <br />　　// Pick the first Connection in the Vector <br />　　// to get round-robin usage <br />　　con = (Connection) freeConnections.firstElement(); <br />　　freeConnections.removeElementAt(0); <br />　　try { <br />　　　if (con.isClosed()) { <br />　　　　log("Removed bad connection from " + name); <br />　　　　// Try again recursively <br />　　　　con = getConnection(); <br />　　　} <br />　　} <br />　　catch (SQLException e) { <br />　　　log("Removed bad connection from " + name); <br />　　　// Try again recursively <br />　　　con = getConnection(); <br />　　} <br />　} <br />　else if (maxConn == 0 || checkedOut &lt; maxConn) { <br />　　con = newConnection(); <br />　} <br />　if (con != null) { <br />　　checkedOut++; <br />　} <br />　return con; <br />} </td></tr></tbody></table><br />　　所有空闲的连接对象保存在一个叫freeConnections 的Vector中。如果存在至少一个空闲的连接，getConnection()返回其中第一个连接。下面，将会看到，进程释放的连接返回到freeConnections的末尾。这样，最大限度地避免了数据库因一个连接不活动而意外将其关闭的风险。 <br /><br />　　再返回客户之前，isClosed()检查连接是否有效。如果连接被关闭了，或者一个错误发生，该方法递归调用取得另一个连接。 <br /><br />　　如果没有可用的连接，该方法检查是否最大连接数被设置为0表示无限连接数，或者达到了最大连接数。如果可以创建新的连接，则创建一个新的连接。否则，返回null。 <br /><br />　　方法newConnection()用来创建一个新的连接。这是一个私有方法，基于用户名和密码来确定是否可以创建新的连接。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>private Connection newConnection() { <br />　Connection con = null; <br />　try { <br />　　if (user == null) { <br />　　 con = DriverManager.getConnection(URL); <br />　　} <br />　　else { <br />　　　con = DriverManager.getConnection(URL, user, password); <br />　　} <br />　　log("Created a new connection in pool " + name); <br />　} <br />　catch (SQLException e) { <br />　　log(e, "Can not create a new connection for " + URL); <br />　　return null; <br />　} <br />　return con; <br />}</td></tr></tbody></table><br />　　jdbc的DriverManager提供一系列的getConnection（）方法，可以使用url和用户名，密码等参数创建一个连接。 <br /><br />　　第二个getConnection()方法带有一个超时参数 timeout,当该参数指定的毫秒数表示客户愿意为一个连接等待的时间。这个方法调用前一个方法。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public synchronized Connection getConnection(long timeout) { <br />　long startTime = new Date().getTime(); <br />　Connection con; <br />　while ((con = getConnection()) == null) { <br />　　try { <br />　　　wait(timeout); <br />　　} <br />　　catch (InterruptedException e) {} <br />　　if ((new Date().getTime() - startTime) &gt;= timeout) { <br />　　　// Timeout has expired <br />　　　return null; <br />　　} <br />　} <br />　return con; <br />} </td></tr></tbody></table><br />　　局部变量startTime初始化当前的时间。一个while循环首先尝试获得一个连接，如果失败，wait()函数被调用来等待需要的时间。后面会看到，Wait()函数会在另一个进程调用notify()或者notifyAll()时返回，或者等到时间流逝完毕。为了确定wait()是因为何种原因返回，我们用开始时间减去当前时间，检查是否大于timeout。如果结果大于timeout,返回null,否则，在此调用getConnection()函数。 <br /><br />　　五、将一个连接返回池中 <br /><br />　　DBConnectionPool类中有一个freeConnection方法以返回的连接作为参数，将连接返回连接池。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public synchronized void freeConnection(Connection con) { <br />　// Put the connection at the end of the Vector <br />　freeConnections.addElement(con); <br />　checkedOut--; <br />　notifyAll(); <br />} </td></tr></tbody></table><br />　　连接被加在freeConnections向量的最后，占用的连接数减1，调用notifyAll()函数通知其他等待的客户现在有了一个连接。 <br /><br />　　六、关闭 <br /><br />　　大多数servlet引擎提供完整的关闭方法。数据库连接池需要得到通知以正确地关闭所有的连接。DBConnectionManager负责协调关闭事件，但连接由各个连接池自己负责关闭。方法relase()由DBConnectionManager调用。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public synchronized void release() { <br />　Enumeration allConnections = freeConnections.elements(); <br />　while (allConnections.hasMoreElements()) { <br />　　Connection con = (Connection) allConnections.nextElement(); <br />　　try { <br />　　　con.close(); <br />　　　log("Closed connection for pool " + name); <br />　　} <br />　　catch (SQLException e) { <br />　　　log(e, "Can not close connection for pool " + name); <br />　　} <br />　} <br />　freeConnections.removeAllElements(); <br />} </td></tr></tbody></table><br />　　本方法遍历freeConnections向量以关闭所有的连接。 <br /><br />　　DBConnetionManager的构造函数是私有函数，以避免其他类创建其实例。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>private DBConnectionManager() { <br /><br />init(); <br /><br />} </td></tr></tbody></table><br />　　DBConnetionManager的客户调用getInstance()方法来得到该类的单一实例的引用。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>static synchronized public DBConnectionManager getInstance() { <br />if (instance == null) { <br />　instance = new DBConnectionManager(); <br />} <br />clients++; <br />return instance; <br />} </td></tr></tbody></table><br /><br /><br /><b>连结池使用实例</b><br /><br />　　单一的实例在第一次调用时创建，以后的调用返回该实例的静态应用。一个计数器纪录所有的客户数，直到客户释放引用。这个计数器在以后用来协调关闭连接池。 <br /><br />　　一、初始化 <br /><br />　　构造函数调用一个私有的init()函数初始化对象。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>private void init() { <br />　InputStream is = getClass().getResourceAsStream("/db.properties"); <br />　Properties dbProps = new Properties(); <br />　try { <br />　　dbProps.load(is); <br />　} <br />　catch (Exception e) { <br />　　System.err.println("Can not read the properties file. " + "Make sure db.properties is in the CLASSPATH"); <br />　　return; <br />　} <br /><br />　String logFile = dbProps.getProperty("logfile", <br />　　　 "DBConnectionManager.log"); <br />　try { <br />　　log = new PrintWriter(new FileWriter(logFile, true), true); <br />　} <br />　catch (IOException e) { <br />　　System.err.println("Can not open the log file: " + logFile); <br />　　log = new PrintWriter(System.err); <br />　} <br />　loadDrivers(dbProps); <br />　createPools(dbProps); <br />} </td></tr></tbody></table><br />　　方法getResourceAsStream()是一个标准方法，用来打开一个外部输入文件。文件的位置取决于类加载器，而标准的类加载器从classpath开始搜索。Db.properties文件是一个Porperties格式的文件，保存在连接池中定义的key-value对。下面一些常用的属性可以定义： <br /><br />　　　drivers 以空格分开的jdbc驱动程序的列表 <br /><br />　　　logfile 日志文件的绝对路径 <br /><br />　　每个连接池中还使用另一些属性。这些属性以连接池的名字开头： <br /><br />　　　.url数据库的JDBC URL <br /><br />　　　.maxconn最大连接数。0表示无限。 <br /><br />　　　.user连接池的用户名 <br /><br />　　　.password相关的密码 <br /><br />　　url属性是必须的，其他属性可选。用户名和密码必须和所定义的数据库匹配。 <br /><br />　　下面是windows平台下的一个db.properties文件的例子。有一个InstantDB连接池和一个通过odbc连接的access数据库的数据源，名字叫demo。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver <br /><br />logfile=D:\\user\\src\\java\\DBConnectionManager\\log.txt <br /><br />idb.url=jdbc:idb:c:\\local\\javawebserver1.1\\db\\db.prp <br /><br />idb.maxconn=2 <br /><br />access.url=jdbc:odbc:demo <br /><br />access.user=demo <br /><br />access.password=demopw </td></tr></tbody></table><br />　　注意，反斜线在windows平台下必须双写。 <br /><br />　　初始化方法init()创建一个Porperties对象并装载db.properties文件，然后读取日志文件属性。如果日志文件没有命名，则使用缺省的名字DBConnectionManager.log在当前目录下创建。在此情况下，一个系统错误被纪录。 <br /><br />　　方法loadDrivers()将指定的所有jdbc驱动程序注册，装载。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>private void loadDrivers(Properties props) { <br />　String driverClasses = props.getProperty("drivers"); <br />　StringTokenizer st = new StringTokenizer(driverClasses); <br />　while (st.hasMoreElements()) { <br />　　String driverClassName = st.nextToken().trim(); <br />　　try { <br />　　　Driver driver = (Driver) <br />　　　Class.forName(driverClassName).newInstance(); <br />　　　DriverManager.registerDriver(driver); <br />　　　drivers.addElement(driver); <br />　　　log("Registered JDBC driver " + driverClassName); <br />　　} <br />　　catch (Exception e) { <br />　　　log("Can not register JDBC driver: " + driverClassName + ", Exception: " + e); <br />　　} <br />　} <br />} </td></tr></tbody></table><br />　　loadDrivers()使用StringTokenizer将dirvers属性分成单独的driver串，并将每个驱动程序装入java虚拟机。驱动程序的实例在JDBC 的DriverManager中注册，并加入一个私有的向量drivers中。向量drivers用来关闭和注销所有的驱动程序。 <br /><br />　　然后，DBConnectionPool对象由私有方法createPools()创建。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>private void createPools(Properties props) { <br />　Enumeration propNames = props.propertyNames(); <br />　while (propNames.hasMoreElements()) { <br />　　String name = (String) propNames.nextElement(); <br />　　if (name.endsWith(".url")) { <br />　　　String poolName = name.substring(0, name.lastIndexOf(".")); <br />　　　String url = props.getProperty(poolName + ".url"); <br />　　　if (url == null) { <br />　　　　log("No URL specified for " + poolName); <br />　　　　continue; <br />　　　} <br />　　　String user = props.getProperty(poolName + ".user"); <br />　　　String password = props.getProperty(poolName + ".password"); <br />　　　String maxconn = props.getProperty(poolName + ".maxconn", "0"); <br />　　　int max; <br />　　　try { <br />　　　　max = Integer.valueOf(maxconn).intValue(); <br />　　　} <br />　　　catch (NumberFormatException e) { <br />　　　　log("Invalid maxconn value " + maxconn + " for " + poolName); <br />　　　　max = 0; <br />　　　} <br />　　　DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max); <br />　　　pools.put(poolName, pool); <br />　　　log("Initialized pool " + poolName); <br />　　} <br />　} <br />} </td></tr></tbody></table><br />　　一个枚举对象保存所有的属性名，如果属性名带有.url结尾，则表示是一个连接池对象需要被实例化。创建的连接池对象保存在一个Hashtable实例变量中。连接池名字作为索引，连接池对象作为值。 <br /><br />　　二、得到和返回连接 <br /><br />　　DBConnectionManager提供getConnection（）方法和freeConnection方法，这些方法有客户程序使用。所有的方法以连接池名字所参数，并调用特定的连接池对象。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public Connection getConnection(String name) { <br />　DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br />　if (pool != null) { <br />　　return pool.getConnection(); <br />　} <br />　return null; <br />} <br /><br />public Connection getConnection(String name, long time) { <br />　DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br />　if (pool != null) { <br />　　return pool.getConnection(time); <br />　} <br />　return null; <br />} <br /><br />public void freeConnection(String name, Connection con) { <br />　DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br />　if (pool != null) { <br />　　pool.freeConnection(con); <br />　} <br />} </td></tr></tbody></table><br />　　三、关闭 <br /><br />　　最后，由一个release（）方法，用来完好地关闭连接池。每个DBConnectionManager客户必须调用getInstance()方法引用。有一个计数器跟踪客户的数量。方法release()在客户关闭时调用，技术器减1。当最后一个客户释放，DBConnectionManager关闭所有的连接池。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>public synchronized void release() { <br />　// Wait until called by the last client <br />　if (--clients != 0) { <br />　　return; <br />　} <br /><br />　Enumeration allPools = pools.elements(); <br />　while (allPools.hasMoreElements()) { <br />　　DBConnectionPool pool = (DBConnectionPool) allPools.nextElement(); <br />　　pool.release(); <br />　} <br /><br />　Enumeration allDrivers = drivers.elements(); <br />　while (allDrivers.hasMoreElements()) { <br />　　Driver driver = (Driver) allDrivers.nextElement(); <br />　　try { <br />　　　DriverManager.deregisterDriver(driver); <br />　　　log("Deregistered JDBC driver " + driver.getClass().getName()); <br />　　} <br />　　catch (SQLException e) { <br />　　　log(e, "Can not deregister JDBC driver: " + driver.getClass().getName()); <br />　　} <br />　} <br />} </td></tr></tbody></table><br />　　当所有连接池关闭，所有jdbc驱动程序也被注销。 <br /><br /><br /><b>连结池的作用</b><br /><br />　　现在我们结合DBConnetionManager和DBConnectionPool类来讲解servlet中连接池的使用： <br /><br />　　一、首先简单介绍一下Servlet的生命周期： <br /><br />　　Servlet API定义的servlet生命周期如下： <br /><br />　　1、 Servlet 被创建然后初始化（init()方法）。 <br /><br />　　2、 为0个或多个客户调用提供服务（service()方法）。 <br /><br />　　3、 Servlet被销毁，内存被回收（destroy()方法）。 <br /><br />　　二、servlet中使用连接池的实例 <br /><br />　　使用连接池的servlet有三个阶段的典型表现是： <br /><br />　　1． 在init()中，调用DBConnectionManager.getInstance()然后将返回的引用保存在实例变量中。 <br /><br />　　2． 在sevice()中，调用getConnection()，执行一系列数据库操作，然后调用freeConnection()归还连接。 <br /><br />　　3． 在destroy()中，调用release()来释放所有的资源，并关闭所有的连接。 <br /><br />　　下面的例子演示如何使用连接池。 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td>import java.io.*; <br />import java.sql.*; <br />import javax.servlet.*; <br />import javax.servlet.http.*; <br /><br />public class TestServlet extends HttpServlet { <br />　private DBConnectionManager connMgr; <br /><br />　public void init(ServletConfig conf) throws ServletException { <br />　　super.init(conf); <br />　　connMgr = DBConnectionManager.getInstance(); <br />　} <br /><br />　public void service(HttpServletRequest req, HttpServletResponse res) <br />　throws IOException { <br />　　res.setContentType("text/html"); <br />　　PrintWriter out = res.getWriter(); <br />　　Connection con = connMgr.getConnection("idb"); <br />　　if (con == null) { <br />　　　out.println("Cant get connection"); <br />　　　return; <br />　　} <br />　　ResultSet rs = null; <br />　　ResultSetMetaData md = null; <br />　　Statement stmt = null; <br />　　try { <br />　　　stmt = con.createStatement(); <br />　　　rs = stmt.executeQuery("SELECT * FROM EMPLOYEE"); <br />　　　md = rs.getMetaData(); <br />　　　out.println("Employee data "); <br />　　　while (rs.next()) { <br />　　　　out.println(" "); <br />　　　　for (int i = 1; i &lt; md.getColumnCount(); i++) { <br />　　　　　out.print(rs.getString(i) + ", "); <br />　　　　} <br />　　　} <br />　　　stmt.close(); <br />　　　rs.close(); <br />　　} <br />　　catch (SQLException e) { <br />　　　e.printStackTrace(out); <br />　　} <br />　　connMgr.freeConnection("idb", con); <br />　} <br />　public void destroy() { <br />　　connMgr.release(); <br />　　super.destroy(); <br />　} <br />} </td></tr></tbody></table><br />  <img src ="http://www.blogjava.net/xixidabao/aggbug/47390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2006-05-21 23:47 <a href="http://www.blogjava.net/xixidabao/archive/2006/05/21/47390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC基础(三)</title><link>http://www.blogjava.net/xixidabao/archive/2006/05/10/45555.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 10 May 2006 14:46:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2006/05/10/45555.html</guid><description><![CDATA[关于Statement对象:<br />    前面说过,Statement对象是用来绑定要执行的操作的,在它上面有三种执行方法:<br />即用来执行查询操作的executeQuery(),用来执行更新操作的executeUpdate()和用来执行<br />动态的未知的操作的execute().<br />    JDBC在编译时并不对要执行的SQL语句检测,只是把它看着一个String,只有在驱动<br />程序执行SQL语句时才知道正确与否.<br />    一个Statement对象同时只能有一个结果集在活动.这是宽容性的,就是说即使没有<br />调用ResultSet的close()方法,只要打开第二个结果集就隐含着对上一个结果集的关闭.所以<br />如果你想同时对多个结果集操作,就要创建多个Statement对象,如果不需要同时操作,那么可<br />以在一个Statement对象上须序操作多个结果集.<br />    <br />    这里我不得不特别说明一下,很多人会用一个Statement进行嵌套查询,然后就来问<br />我说为什么不能循环?道理上面已经说清楚了.我们来详细分析一下嵌套查询:<br />    Connection conn = null;<br />    Statement stmt = null;<br />    conn = .......;<br />    stmt = conm.createStatement(xxxxxx);<br />    ResultSet rs = stmt.executeQuery(sql1);<br />    while(rs.next()){<br />        str = rs.getString(xxxxx);<br />        ResultSet rs1 = stmt.executeQuery(\"select * from 表 where 字段=str\");<br />    }<br />当stmt.executeQuery(\"select * from 表 where 字段=str\");赋给rs1时,这时隐含的操作<br />是已经关闭了rs,你还能循环下去吗?<br />所以如果要同时操作多个结果集一定要让它他绑定到不同的Statement对象上.好在一个connection<br />对象可以创建任意多个Statement对象,而不需要你重新获取连结.<br /><br />    关于获取和设置Statement的选项:只要看看它的getXXX方法和setXXX方法就明白了,这儿<br />作为基础知识只提一下以下几个:<br />    setQueryTimeout,设置一个SQL执行的超时限制.<br />    setMaxRows,设置结果集能容纳的行数.<br />    setEscapeProcessing,如果参数为true,则驱动程序在把SQL语句发给数据库前进行转义替<br />换,否则让数据库自己处理,当然这些默认值都可以通过get方法查询.<br /><br />    Statement的两个子类:<br />    PreparedStatement:对于同一条语句的多次执行,Statement每次都要把SQL语句发送给数据<br />库,这样做效率明显不高,而如果数据库支持预编译,PreparedStatement可以先把要执行的语句一次发<br />给它,然后每次执行而不必发送相同的语句,效率当然提高,当然如果数据库不支持预编译,<br />PreparedStatement会象Statement一样工作,只是效率不高而不需要用户工手干预.<br />    另外PreparedStatement还支持接收参数.在预编译后只要传输不同的参数就可以执行,大大<br />提高了性能.<br />        <br />    PreparedStatement ps = conn.prepareStatement(\"select * from 表 where 字段=?\");<br />    ps.setString(1,参数);<br />    ResultSet rs = ps.executeQuery();<br />    <br />    CallableStatement:是PreparedStatement的子类,它只是用来执行存储过程的.<br />    CallableStatement sc = conn.prepareCall(\"{call query()}\");<br />    ResultSet rs = cs.executeQuery();<br />    <br />    关于更高级的知识我们在JDBC高级应用中介绍.  <img src ="http://www.blogjava.net/xixidabao/aggbug/45555.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2006-05-10 22:46 <a href="http://www.blogjava.net/xixidabao/archive/2006/05/10/45555.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>