??xml version="1.0" encoding="utf-8" standalone="yes"?>2021中文字幕一区亚洲,欧美日韩一区中文字幕,亚洲天堂成人在线http://www.aygfsteel.com/shuqinpeng/category/2566.htmlJAVA的学?fn)历E?/description>zh-cnTue, 27 Feb 2007 12:16:36 GMTTue, 27 Feb 2007 12:16:36 GMT60JDBC 指南QCallableStatementhttp://www.aygfsteel.com/shuqinpeng/articles/9370.htmlPS@JAVAPS@JAVAFri, 05 Aug 2005 02:18:00 GMThttp://www.aygfsteel.com/shuqinpeng/articles/9370.htmlhttp://www.aygfsteel.com/shuqinpeng/comments/9370.htmlhttp://www.aygfsteel.com/shuqinpeng/articles/9370.html#Feedback0http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9370.htmlhttp://www.aygfsteel.com/shuqinpeng/services/trackbacks/9370.html本概q是从《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》这本书中摘引来的。JavaSoft 目前正在准备q本书。这本书是一本教E,同时也是 JDBC 的重要参考手册,它将作ؓ(f) Java pd的组成部份在 1997 q春季由 Addison-Wesley 出版公司出版?nbsp;


7.1 概述
CallableStatement 对象为所有的 DBMS 提供?jin)一U以标准形式调用已储存过E的Ҏ(gu)。已储存q程储存在数据库中。对已储存过E的调用?nbsp;CallableStatement 对象所含的内容。这U调用是用一U换码语法来写的Q有两种形式Q一UŞ式带l果参数Q另一UŞ式不带结果参敎ͼ有关换码语法的信息,参见W?nbsp;4 节“语句”)(j)。结果参数是一U输?nbsp;(OUT) 参数Q是已储存过E的q回倹{两UŞ式都可带有数量可变的输入QIN 参数Q、输出(OUT 参数Q或输入和输出(INOUT 参数Q的参数。问号将用作参数的占位符?

?nbsp;JDBC 中调用已储存q程的语法如下所C。注意,Ҏ(gu)可C其间的内容是可选项Q方括号本nq不是语法的l成部䆾?

{call q程名[(?, ?, ...)]}

q回l果参数的过E的语法为:(x) 

{? = call q程名[(?, ?, ...)]}

不带参数的已储存q程的语法类|(x) 

{call q程名}

通常Q创?nbsp;CallableStatement 对象的h应当知道所用的 DBMS 是支持已储存q程的,q且知道q些q程都是些什么。然而,如果需要检查,多种 DatabaseMetaData Ҏ(gu)都可以提供这L(fng)信息。例如,如果 DBMS 支持已储存过E的调用Q则 supportsStoredProcedures Ҏ(gu)返?nbsp;trueQ?nbsp;getProcedures Ҏ(gu)返回对已储存过E的描述?

CallableStatement l承 Statement 的方法(它们用于处理一般的 SQL 语句Q,q承了(jin) PreparedStatement 的方法(它们用于处理 IN 参数Q。CallableStatement 中定义的所有方法都用于处理 OUT 参数?nbsp;INOUT 参数的输出部分:(x)注册 OUT 参数?nbsp;JDBC cdQ一?nbsp;SQL cdQ、从q些参数中检索结果,或者检查所q回的值是否ؓ(f) JDBC NULL?


7.1.1 创徏 CallableStatement 对象
CallableStatement 对象是用 Connection Ҏ(gu) prepareCall 创徏的。下例创?nbsp;CallableStatement 的实例,其中含有对已储存q程 getTestData 调用。该q程有两个变量,但不含结果参敎ͼ(x) 

CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}");

其中 ? 占位Wؓ(f) IN?nbsp;OUT q是 INOUT 参数Q取决于已储存过E?nbsp;getTestData?


7.1.2 IN ?nbsp;OUT 参数
?nbsp;IN 参数传给 CallableStatement 对象是通过 setXXX Ҏ(gu)完成的。该Ҏ(gu)l承?nbsp;PreparedStatement。所传入参数的类型决定了(jin)所用的 setXXX Ҏ(gu)Q例如,?nbsp;setFloat 来传?nbsp;float 值等Q?

如果已储存过E返?nbsp;OUT 参数Q则在执?nbsp;CallableStatement 对象以前必须先注册每?nbsp;OUT 参数?nbsp;JDBC cdQ这是必需的,因ؓ(f)某些 DBMS 要求 JDBC cdQ。注?nbsp;JDBC cd是用 registerOutParameter Ҏ(gu)来完成的。语句执行完后,CallableStatement ?nbsp;getXXX Ҏ(gu)取回参数倹{正的 getXXX Ҏ(gu)是ؓ(f)各参数所注册?nbsp;JDBC cd所对应?nbsp;Java cdQ从 JDBC cd?nbsp;Java cd的标准映见 8.6.1 节中的表Q。换a之, registerOutParameter 使用的是 JDBC cdQ因此它与数据库q回?nbsp;JDBC cd匚wQ,?nbsp;getXXX 之转换?nbsp;Java cd?

作ؓ(f)CZQ下qC码先注册 OUT 参数Q执行由 cstmt 所调用的已储存q程Q然后检索在 OUT 参数中返回的倹{方?nbsp;getByte 从第一?nbsp;OUT 参数中取Z?nbsp;Java 字节Q?nbsp;getBigDecimal 从第二个 OUT 参数中取Z?nbsp;BigDecimal 对象Q小数点后面带三位数Q:(x) 

CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}");
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3);
cstmt.executeQuery();
byte x = cstmt.getByte(1);
java.math.BigDecimal n = cstmt.getBigDecimal(2, 3);

CallableStatement ?nbsp;ResultSet 不同Q它不提供用增量方式(g)索大 OUT 值的Ҏ(gu)机制?


7.1.3 INOUT 参数
既支持输入又接受输出的参敎ͼINOUT 参数Q除?jin)调?nbsp;registerOutParameter Ҏ(gu)外,q要求调用适当?nbsp;setXXX Ҏ(gu)Q该Ҏ(gu)是从 PreparedStatement l承来的Q。setXXX Ҏ(gu)参数D|ؓ(f)输入参数Q?nbsp;registerOutParameter Ҏ(gu)它?nbsp;JDBC cd注册出参数。setXXX Ҏ(gu)提供一?nbsp;Java |而驱动程序先把这个D{换ؓ(f) JDBC |然后它送到数据库中?

q种 IN 值的 JDBC cd和提供给 registerOutParameter Ҏ(gu)?nbsp;JDBC cd应该相同。然后,要检索输出|p用对应的 getXXX Ҏ(gu)。例如,Java cd?nbsp;byte 的参数应该用方?nbsp;setByte 来赋输入倹{应该给 registerOutParameter 提供cd?nbsp;TINYINT ?nbsp;JDBC cdQ同时应使用 getByte 来检索输出?nbsp;Q第 8 节“JDBC ?nbsp;Java cd之间的映”将l出详细信息和类型映表Q?

下例假设有一个已储存q程 reviseTotalQ其唯一参数?nbsp;INOUT 参数。方?nbsp;setByte 把此参数设ؓ(f) 25Q驱动程序将把它作ؓ(f) JDBC TINYINT cd送到数据库中。接着QregisterOutParameter 该参数注册?nbsp;JDBC TINYINT。执行完该已储存q程后,返回一个新?nbsp;JDBC TINYINT 倹{方?nbsp;getByte 把q个新g?nbsp;Java byte cd(g)索?

CallableStatement cstmt = con.prepareCall(
"{call reviseTotal(?)}");
cstmt.setByte(1, 25);
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.executeUpdate();
byte x = cstmt.getByte(1);

7.1.4 先检索结果,再检?nbsp;OUT 参数
׃某些 DBMS 的限ӞZ(jin)实现最大的可移植性,先检索由执行 CallableStatement 对象所产生的结果,然后再用 CallableStatement.getXXX Ҏ(gu)来检?nbsp;OUT 参数?

如果 CallableStatement 对象q回多个 ResultSet 对象Q通过调用 execute Ҏ(gu)Q,在检?nbsp;OUT 参数前应先检索所有的l果。这U情况下Qؓ(f)保Ҏ(gu)有的l果都进行了(jin)讉KQ必d Statement Ҏ(gu) getResultSet、getUpdateCount ?nbsp;getMoreResults q行调用Q直C再有l果为止?

(g)索完所有的l果后,可?nbsp;CallableStatement.getXXX Ҏ(gu)来检?nbsp;OUT 参数中的倹{?


7.1.5 (g)索作?nbsp;OUT 参数?nbsp;NULL ?
q回?nbsp;OUT 参数中的值可能会(x)?nbsp;JDBC NULL。当出现q种情ŞӞ对 JDBC NULL D行{换以?nbsp;getXXX Ҏ(gu)所q回的gؓ(f) null? ?nbsp;falseQ这取决?nbsp;getXXX Ҏ(gu)cd。对?nbsp;ResultSet 对象Q要知道 0 ?nbsp;false 是否源于 JDBC NULL 的唯一Ҏ(gu)Q是用方?nbsp;wasNull q行(g)。如?nbsp;getXXX Ҏ(gu)d的最后一个值是 JDBC NULLQ则该方法返?nbsp;trueQ否则返?nbsp;flase。第 5 节“ResultSet”将l出详细信息?

PS@JAVA 2005-08-05 10:18 发表评论
]]>
JDBC 指南QPreparedStatementhttp://www.aygfsteel.com/shuqinpeng/articles/9369.htmlPS@JAVAPS@JAVAFri, 05 Aug 2005 02:17:00 GMThttp://www.aygfsteel.com/shuqinpeng/articles/9369.htmlhttp://www.aygfsteel.com/shuqinpeng/comments/9369.htmlhttp://www.aygfsteel.com/shuqinpeng/articles/9369.html#Feedback0http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9369.htmlhttp://www.aygfsteel.com/shuqinpeng/services/trackbacks/9369.html本概q是从《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》这本书中摘引来的。JavaSoft 目前正在准备q本书。这是一本教E,同时也是 JDBC 的重要参考手册,它将作ؓ(f) Java pd的组成部份在 1997 q春季由 Addison-Wesley 出版公司出版?nbsp;


6.1 概述
?nbsp;PreparedStatement 接口l承 StatementQƈ与之在两斚w有所不同Q?nbsp;


PreparedStatement 实例包含已编译的 SQL 语句。这是使语句“准备好”?nbsp;
包含?nbsp;PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN 参数的值在 SQL 语句创徏时未被指定。相反的Q该语句为每?nbsp;IN 参数保留一个问P“?”)(j)作ؓ(f)占位W。每个问L(fng)值必d该语句执行之前,通过适当?nbsp;setXXX Ҏ(gu)来提供?nbsp;

׃ PreparedStatement 对象已预~译q,所以其执行速度要快?nbsp;Statement 对象。因此,多次执行?nbsp;SQL 语句l常创徏?nbsp;PreparedStatement 对象Q以提高效率?

作ؓ(f) Statement 的子c,PreparedStatement l承?nbsp;Statement 的所有功能。另外它q添加了(jin)一整套Ҏ(gu)Q用于设|发送给数据库以取代 IN 参数占位W的倹{同Ӟ三种Ҏ(gu) execute?nbsp;executeQuery ?nbsp;executeUpdate 已被更改以之不再需要参数。这些方法的 Statement 形式Q接?nbsp;SQL 语句参数的Ş式)(j)不应该用?nbsp;PreparedStatement 对象?


6.1.1 创徏 PreparedStatement 对象
以下的代码段Q其?nbsp;con ?nbsp;Connection 对象Q创建包含带两个 IN 参数占位W的 SQL 语句?nbsp;PreparedStatement 对象Q?nbsp;

PreparedStatement pstmt = con.prepareStatement(
"UPDATE table4 SET m = ? WHERE x = ?");

pstmt 对象包含语句 "UPDATE table4 SET m = ? WHERE x = ?"Q它已发送给 DBMSQƈ为执行作好了(jin)准备?


6.1.2 传?nbsp;IN 参数
在执?nbsp;PreparedStatement 对象之前Q必设|每?nbsp;? 参数的倹{这可通过调用 setXXX Ҏ(gu)来完成,其中 XXX 是与该参数相应的cd。例如,如果参数h Java cd longQ则使用的方法就?nbsp;setLong。setXXX Ҏ(gu)的第一个参数是要设|的参数的序C|,W二个参数是讄l该参数的倹{例如,以下代码第一个参数设?nbsp;123456789Q第二个参数设ؓ(f) 100000000Q?nbsp;

pstmt.setLong(1, 123456789);
pstmt.setLong(2, 100000000);

一旦设|了(jin)l定语句的参数|可用它多次执行该语句,直到调用 clearParameters Ҏ(gu)清除它ؓ(f)止?

在连接的~省模式下(启用自动提交Q,当语句完成时自动提交或q原该语句?

如果基本数据库和驱动E序在语句提交之后仍保持q些语句的打开状态,则同一?nbsp;PreparedStatement 可执行多ơ。如果这一点不成立Q那么试N过使用 PreparedStatement 对象代替 Statement 对象来提高性能是没有意义的?

利用 pstmtQ前面创建的 PreparedStatement 对象Q,以下代码例示?jin)如何设|两个参数占位符的值ƈ执行 pstmt 10 ơ。如上所qͼ为做到这一点,数据库不能关?nbsp;pstmt。在该示例中Q第一个参数被讄?nbsp;"Hi"q保持ؓ(f)常数。在 for 循环中,每次都将W二个参数设|ؓ(f)不同的|(x)?nbsp;0 开始,?nbsp;9 l束?

pstmt.setString(1, "Hi");
for (int i = 0; i < 10; i++) {
pstmt.setInt(2, i);
int rowCount = pstmt.executeUpdate();
}

6.1.3 IN 参数中数据类型的一致?
setXXX Ҏ(gu)中的 XXX ?nbsp;Java cd。它是一U隐含的 JDBC cdQ一?nbsp;SQL cdQ,因ؓ(f)驱动E序把 Java cd映射为相应的 JDBC cdQ遵循该 JDBC Guide中?.6.2 “映?nbsp;Java ?nbsp;JDBC cd”表中所指定的映)(j)Qƈ该 JDBC cd发送给数据库。例如,以下代码D将 PreparedStatement 对象 pstmt 的第二个参数讄?nbsp;44QJava cd?nbsp;shortQ?nbsp;

pstmt.setShort(2, 44);

驱动E序?nbsp;44 作ؓ(f) JDBC SMALLINT 发送给数据库,它是 Java short cd的标准映?

E序员的责Q是确保将每个 IN 参数?nbsp;Java cd映射Z数据库所需?nbsp;JDBC 数据cd兼容?nbsp;JDBC cd。不妨考虑数据库需?nbsp;JDBC SMALLINT 的情c(din)如果用方?nbsp;setByte Q则驱动E序?nbsp;JDBC TINYINT 发送给数据库。这是可行的Q因多数据库可从一U相关的cd转换为另一U类型,q且通常 TINYINT 可用?nbsp;SMALLINT 适用的Q何地斏V然而,对于要适用于尽可能多的数据库的应用E序Q最好用与数据库所需的确切的 JDBC cd相应?nbsp;Java cd。如果所需?nbsp;JDBC cd?nbsp;SMALLINTQ则使用 setShort 代替 setByte 应用E序的可UL性更好?


6.1.4 使用 setObject
E序员可使用 setObject Ҏ(gu)昑ּ地将输入参数转换为特定的 JDBC cd。该Ҏ(gu)可以接受W三个参敎ͼ用来指定目标 JDBC cd。将 Java Object 发送给数据库之前,驱动E序把它{换ؓ(f)指定?nbsp;JDBC cd?

如果没有指定 JDBC cdQ驱动程序就?x)?nbsp;Java Object 映射到其~省?nbsp;JDBC cdQ参见第 8.6.4 节中的表|(j)Q然后将它发送到数据库。这与常规的 setXXX Ҏ(gu)cMQ在q两U情况下Q驱动程序在值发送到数据库之前,?x)将该值的 Java cd映射为适当?nbsp;JDBC cd。二者的差别在于 setXXX Ҏ(gu)使用?nbsp;Java cd?nbsp;JDBC cd的标准映(参见W?nbsp;8.6.2 节中的表|(j)Q?nbsp;setObject Ҏ(gu)使用?nbsp;Java Object cd?nbsp;JDBC cd的映(参见W?nbsp;8.6.4 节中的表|(j)?

Ҏ(gu) setObject 允许接受所?nbsp;Java 对象的能力应用E序更ؓ(f)通用Qƈ可在q行时接受参数的输入。这U情况下Q应用程序在~译时ƈ不清楚输入类型。通过使用 setObjectQ应用程序可接受所?nbsp;Java 对象cd作ؓ(f)输入Qƈ其转换为数据库所需?nbsp;JDBC cd。第 8.6.5 节中的表格显CZ(jin) setObject 可执行的所有可能{换?


6.1.5 ?nbsp;JDBC NULL 作ؓ(f) IN 参数发?
setNull Ҏ(gu)允许E序员将 JDBC NULL g?nbsp;IN 参数发送给数据库。但要注意,仍然必须指定参数?nbsp;JDBC cd?

当把 Java null g递给 setXXX Ҏ(gu)Ӟ如果它接?nbsp;Java 对象作ؓ(f)参数Q,也将同样?nbsp;JDBC NULL 发送到数据库。但仅当指定 JDBC cdӞҎ(gu) setObject 才能接受 null 倹{?


6.1.6 发送大?nbsp;IN 参数
setBytes ?nbsp;setString Ҏ(gu)能够发送无限量的数据。但是,有时E序员更喜欢用较?yu)的块传递大型的数据。这可通过?nbsp;IN 参数讄?nbsp;Java 输入来完成。当语句执行ӞJDBC 驱动E序重复调用该输入,d其内容ƈ它们当作实际参数数据传输?

JDBC 提供?jin)三U将 IN 参数讄入流的方法:(x)setBinaryStream 用于含有未说明字节的, setAsciiStream 用于含有 ASCII 字符的流Q?nbsp;setUnicodeStream 用于含有 Unicode 字符的流。因为必L定流的总长度,所以这些方法所采用的参数比其它?nbsp;setXXX Ҏ(gu)要多一个。这很有必要Q因Z些数据库在发送数据之前需要知道其ȝ传送大?

以下代码例示?jin)用流作?f) IN 参数来发送文件内容:(x) 

java.io.File file = new java.io.File("/tmp/data");
int fileLength = file.length();
java.io.InputStream fin = new java.io.FileInputStream(file);
java.sql.PreparedStatement pstmt = con.prepareStatement(
"UPDATE Table5 SET stuff = ? WHERE index = 4");
pstmt.setBinaryStream (1, fin, fileLength);
pstmt.executeUpdate();

当语句执行时Q将反复调用输入?nbsp;fin 以传递其数据?

PS@JAVA 2005-08-05 10:17 发表评论
]]>
JDBC 指南QStatementhttp://www.aygfsteel.com/shuqinpeng/articles/9367.htmlPS@JAVAPS@JAVAFri, 05 Aug 2005 02:16:00 GMThttp://www.aygfsteel.com/shuqinpeng/articles/9367.htmlhttp://www.aygfsteel.com/shuqinpeng/comments/9367.htmlhttp://www.aygfsteel.com/shuqinpeng/articles/9367.html#Feedback0http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9367.htmlhttp://www.aygfsteel.com/shuqinpeng/services/trackbacks/9367.html4 - Statement
本概q是从《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》这本书中摘引来的。JavaSoft 目前正在准备q本书。这是一本教E,同时也是 JDBC 的重要参考手册,它将作ؓ(f) Java pd的组成部份在 1997 q春季由 Addison-Wesley 出版公司出版?


4.1 概述
Statement 对象用于?SQL 语句发送到数据库中。实际上有三U?Statement 对象Q它们都作ؓ(f)在给定连接上执行 SQL 语句的包容器QStatement、PreparedStatementQ它?Statement l承而来Q和 CallableStatementQ它?PreparedStatement l承而来Q。它们都专用于发送特定类型的 SQL 语句Q?Statement 对象用于执行不带参数的简?SQL 语句QPreparedStatement 对象用于执行带或不带 IN 参数的预~译 SQL 语句QCallableStatement 对象用于执行Ҏ(gu)据库已存储过E的调用?BR>
Statement 接口提供?jin)执行语句和获取l果的基本方法。PreparedStatement 接口d?jin)处?IN 参数的方法;?CallableStatement d?jin)处?OUT 参数的方法?BR>

4.1.1 创徏 Statement 对象
建立?jin)到特定数据库的q接之后Q就可用该连接发?SQL 语句。Statement 对象?Connection 的方?createStatement 创徏Q如下列代码D中所C:(x)

Connection con = DriverManager.getConnection(url, "sunny", "");
Statement stmt = con.createStatement();

Z(jin)执行 Statement 对象Q被发送到数据库的 SQL 语句被作ؓ(f)参数提供l?Statement 的方法:(x)

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");

4.1.2 使用 Statement 对象执行语句
Statement 接口提供?jin)三U执?SQL 语句的方法:(x)executeQuery、executeUpdate ?execute。用哪一个方法由 SQL 语句所产生的内容决定?BR>
Ҏ(gu) executeQuery 用于产生单个l果集的语句Q例?SELECT 语句?BR>
Ҏ(gu) executeUpdate 用于执行 INSERT、UPDATE ?DELETE 语句以及(qing) SQL DDLQ数据定义语aQ语句,例如 CREATE TABLE ?DROP TABLE。INSERT、UPDATE ?DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整敎ͼ指示受媄(jing)响的行数Q即更新计数Q。对?CREATE TABLE ?DROP TABLE {不操作行的语句QexecuteUpdate 的返回值Mؓ(f)零?BR>
Ҏ(gu) execute 用于执行q回多个l果集、多个更新计数或二者组合的语句。因为多数程序员不会(x)需要该高功能Q所以本概述后面在单独一节中对其q行介绍?BR>
执行语句的所有方法都关闭所调用?Statement 对象的当前打开l果集(如果存在Q。这意味着在重新执?Statement 对象之前Q需要完成对当前 ResultSet 对象的处理?BR>
应注意,l承?Statement 接口中所有方法的 PreparedStatement 接口都有自己?executeQuery、executeUpdate ?execute Ҏ(gu)。Statement 对象本n不包?SQL 语句Q因而必ȝ Statement.execute Ҏ(gu)提供 SQL 语句作ؓ(f)参数。PreparedStatement 对象q不?SQL 语句作ؓ(f)参数提供l这些方法,因ؓ(f)它们已经包含预编?SQL 语句。CallableStatement 对象l承q些Ҏ(gu)?PreparedStatement 形式。对于这些方法的 PreparedStatement ?CallableStatement 版本Q用查询参数将抛出 SQLException?BR>

4.1.3 语句完成
当连接处于自动提交模式时Q其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时Q即认ؓ(f)已完成。对于返回一个结果集?executeQuery Ҏ(gu)Q在(g)索完 ResultSet 对象的所有行时该语句完成。对于方?executeUpdateQ当它执行时语句卛_成。但在少数调用方?execute 的情况中Q在(g)索所有结果集或它生成的更新计C后语句才完成?BR>
有些 DBMS 已存储q程中的每条语句视ؓ(f)独立的语句;而另外一些则整个过E视Z个复合语句。在启用自动提交Ӟq种差别变得非帔R要,因ؓ(f)它媄(jing)响什么时候调?commit Ҏ(gu)。在前一U情况中Q每条语句单独提交;在后一U情况中Q所有语句同时提交?BR>

4.1.4 关闭 Statement 对象
Statement 对象由 Java 垃圾攉E序自动关闭。而作ZU好的编E风|应在不需?Statement 对象时显式地关闭它们。这立即释?DBMS 资源Q有助于避免潜在的内存问题?BR>

4.1.5 Statement 对象中的 SQL 转义语法
Statement 可包含?SQL 转义语法?SQL 语句。{义语法告诉驱动程序其中的代码应该以不同方式处理。驱动程序将扫描M转义语法Qƈ它转换成特定数据库可理解的代码。这使得转义语法?DBMS 无关Qƈ允许E序员用在没有转义语法时不可用的功能?BR>
转义子句p括号和关键字界定Q?

{keyword . . . parameters . . . }

该关键字指示转义子句的类型,如下所C?BR>

escape 表示 LIKE 转义字符


字符?”和“_”类g SQL LIKE 子句中的通配W(?”匹配零个或多个字符Q而“_”则匚w一个字W)(j)。ؓ(f)?jin)正解释它们,应在其前面加上反斜杠Q“\”)(j)Q它是字W串中的Ҏ(gu)转义字符。在查询末尾包括如下语法卛_指定用作转义字符的字W:(x)

{escape 'escape-character'}


例如Q下列查询用反斜杠字符作ؓ(f)转义字符Q查找以下划U开头的标识W名Q?

stmt.executeQuery("SELECT name FROM Identifiers
WHERE Id LIKE `\_%' {escape `\'};


fn 表示标量函数


几乎所?DBMS 都具有标量值的数倹{字W串、时间、日期、系l和转换函数。要使用q些函数Q可使用如下转义语法Q关键字 fn 后跟所需的函数名?qing)其参数。例如,下列代码调用函数 concat 两个参数连接在一P(x)

{fn concat("Hot", "Java")};


可用下列语法获得当前数据库用户名Q?

{fn user()};


标量函数可能p法稍有不同的 DBMS 支持Q而它们可能不被所有驱动程序支持。各U?DatabaseMetaData Ҏ(gu)列出所支持的函数。例如,Ҏ(gu) getNumericFunctions q回用逗号分隔的数值函数列表,而方?getStringFunctions 返回字W串函数Q等{?BR>
驱动E序{义函数调用映ؓ(f)相应的语法,或直接实现该函数?BR>

d、t ?ts 表示日期和时间文?BR>

DBMS 用于日期、时间和旉标记文字的语法各不相同。JDBC 使用转义子句支持q些文字的语法的 ISO 标准格式。驱动程序必d转义子句转换?DBMS 表示?BR>
例如Q可用下列语法在 JDBC SQL 语句中指定日期:(x)

{d `yyyy-mm-dd'}


在该语法中,yyyy 为年代,mm 为月份,?dd 则ؓ(f)日期。驱动程序将用等L(fng)特定?DBMS 的表C替换这个{义子句。例如,如果 '28- FEB-99' W合基本数据库的格式Q则驱动E序用它替?{d 1999-02-28}?BR>
对于 TIME ?TIMESTAMP 也有cM的{义子句:(x)

{t `hh:mm:ss'}
{ts `yyyy-mm-dd hh:mm:ss.f . . .'}


TIMESTAMP 中的数点后的秒Q?f . . .Q部分可忽略?BR>

call ?? = call 表示已存储过E?BR>


如果数据库支持已存储q程Q则可从 JDBC 中调用它们,语法为:(x)

{call procedure_name[(?, ?, . . .)]}


或(其中q程q回l果参数Q:(x)

{? = call procedure_name[(?, ?, . . .)]}


Ҏ(gu)hC其中的内容是可选的。它们不是语法的必要部分?BR>
输入参数可以为文字或参数。有兌l信息,参见 JDBC 指南中第 7 节,“CallableStatement”?BR>
可通过调用Ҏ(gu) DatabaseMetaData.supportsStoredProcedures (g)查数据库是否支持已存储过E?BR>


oj 表示外部q接



外部q接的语法ؓ(f)

{oj outer-join}


其中 outer-join 形式?

table LEFT OUTER JOIN {table / outer-join} ON search-condition


外部q接属于高功能。有兛_们的解释可参?SQL 语法。JDBC 提供?jin)三U?DatabaseMetaData Ҏ(gu)用于定驱动E序支持哪些外部q接cdQsupportsOuterJoins、supportsFullOuterJoins ?supportsLimitedOuterJoins?BR>

Ҏ(gu) Statement.setEscapeProcessing 可打开或关闭{义处理;~省状态ؓ(f)打开。当性能极ؓ(f)重要ӞE序员可能想关闭它以减少处理旉。但通常它将Z打开状态。应注意Q?setEscapeProcessing 不适用?PreparedStatement 对象Q因为在调用该语句前它就可能已被发送到数据库。有关预~译的信息,参见 PreparedStatement?BR>

4.1.6 使用Ҏ(gu) execute
execute Ҏ(gu)应该仅在语句能返回多?ResultSet 对象、多个更新计数或 ResultSet 对象与更新计数的l合时用。当执行某个已存储过E或动态执行未?SQL 字符Ԍ卛_用程序程序员在编译时未知Q时Q有可能出现多个l果的情况,管q种情况很少见。例如,用户可能执行一个已存储q程Q?CallableStatement 对象 - 参见W?135 늚 CallableStatementQ,q且该已存储q程可执行更斎ͼ然后执行选择Q再q行更新Q再q行选择Q等{。通常使用已存储过E的人应知道它所q回的内宏V?BR>
因ؓ(f)Ҏ(gu) execute 处理非常规情况,所以获取其l果需要一些特D处理ƈ不为怪。例如,假定已知某个q程q回两个l果集,则在使用Ҏ(gu) execute 执行该过E后Q必调用方?getResultSet 获得W一个结果集Q然后调用适当?getXXX Ҏ(gu)获取其中的倹{要获得W二个结果集Q需要先调用 getMoreResults Ҏ(gu)Q然后再调用 getResultSet Ҏ(gu)。如果已知某个过E返回两个更新计敎ͼ则首先调用方?getUpdateCountQ然后调?getMoreResultsQƈ再次调用 getUpdateCount?BR>
对于不知道返回内容,则情冉|为复杂。如果结果是 ResultSet 对象Q则Ҏ(gu) execute q回 trueQ如果结果是 Java intQ则q回 false。如果返?intQ则意味着l果是更新计数或执行的语句是 DDL 命o(h)。在调用Ҏ(gu) execute 之后要做的第一件事情是调用 getResultSet ?getUpdateCount。调用方?getResultSet 可以获得两个或多?ResultSet 对象中第一个对象;或调用方?getUpdateCount 可以获得两个或多个更新计CW一个更新计数的内容?BR>
?SQL 语句的结果不是结果集Ӟ则方?getResultSet 返?null。这可能意味着l果是一个更新计数或没有其它l果。在q种情况下,判断 null 真正含义的唯一Ҏ(gu)是调用方?getUpdateCountQ它?yu)返回一个整数。这个整Cؓ(f)调用语句所影响的行敎ͼ如果?-1 则表C结果是l果集或没有l果。如果方?getResultSet 已返?nullQ表C结果不?ResultSet 对象Q,则返回?-1 表示没有其它l果。也是_(d)当下列条件ؓ(f)真时表示没有l果Q或没有其它l果Q:(x)

((stmt.getResultSet() == null) && (stmt.getUpdateCount() == -1))

如果已经调用Ҏ(gu) getResultSet q处理了(jin)它返回的 ResultSet 对象Q则有必要调用方?getMoreResults 以确定是否有其它l果集或更新计数。如?getMoreResults q回 trueQ则需要再ơ调?getResultSet 来检索下一个结果集。如上所qͼ如果 getResultSet q回 nullQ则需要调?getUpdateCount 来检?null 是表C结果ؓ(f)更新计数q是表示没有其它l果?BR>
?getMoreResults q回 false Ӟ它表C SQL 语句q回一个更新计数或没有其它l果。因此需要调用方?getUpdateCount 来检查它是哪一U情c(din)在q种情况下,当下列条件ؓ(f)真时表示没有其它l果Q?

((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))

下面的代码演CZ(jin)一U方法用来确认已讉K调用Ҏ(gu) execute 所产生的全部结果集和更新计敎ͼ(x)


stmt.execute(queryStringWithUnknownResults);
while (true) {
int rowCount = stmt.getUpdateCount();
if (rowCount > 0) { // 它是更新计数
System.out.println("Rows changed = " + count);
stmt.getMoreResults();
continue;
}
if (rowCount == 0) { // DDL 命o(h)?0 个更?BR>System.out.println(" No rows changed or statement was DDL
command");
stmt.getMoreResults();
continue;
}

// 执行到这里,证明有一个结果集
// 或没有其它结?BR>
ResultSet rs = stmt.getResultSet;
if (rs != null) {
. . . // 使用元数据获得关于结果集列的信息
while (rs.next()) {
. . . // 处理l果
stmt.getMoreResults();
continue;
}
break; // 没有其它l果



PS@JAVA 2005-08-05 10:16 发表评论
]]>
JDBC 指南QResultSethttp://www.aygfsteel.com/shuqinpeng/articles/9368.htmlPS@JAVAPS@JAVAFri, 05 Aug 2005 02:16:00 GMThttp://www.aygfsteel.com/shuqinpeng/articles/9368.htmlhttp://www.aygfsteel.com/shuqinpeng/comments/9368.htmlhttp://www.aygfsteel.com/shuqinpeng/articles/9368.html#Feedback0http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9368.htmlhttp://www.aygfsteel.com/shuqinpeng/services/trackbacks/9368.html本概q是从《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》这本书中摘引来的。JavaSoft 目前正在准备q本书。这是一本教E,同时也是 JDBC 的重要参考手册,它将作ؓ(f) Java pd的组成部份在 1997 q春季由 Addison-Wesley 出版公司出版?nbsp;


5.1 概述
ResultSet 包含W合 SQL 语句中条件的所有行Qƈ且它通过一?nbsp;get Ҏ(gu)Q这?nbsp;get Ҏ(gu)可以讉K当前行中的不同列Q提供了(jin)对这些行中数据的讉K。ResultSet.next Ҏ(gu)用于Ud?nbsp;ResultSet 中的下一行,使下一行成为当前行?

l果集一般是一个表Q其中有查询所q回的列标题?qing)相应的倹{例如,如果查询?nbsp;SELECT a, b, c FROM Table1Q则l果集将h如下形式Q?nbsp;


a b c
-------- --------- --------
12345 Cupertino CA
83472 Redmond WA
83492 Boston MA


下面的代码段是执?nbsp;SQL 语句的示例。该 SQL 语句返回行集合Q其中列 1 ?nbsp;intQ列 2 ?nbsp;StringQ而列 3 则ؓ(f)字节数组Q?nbsp;


java.sql.Statement stmt = conn.createStatement();
ResultSet r = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (r.next())
{
// 打印当前行的倹{?
int i = r.getInt("a");
String s = r.getString("b");
float f = r.getFloat("c");
System.out.println("ROW = " + i + " " + s + " " + f);
}

5.1.1 行和光标
ResultSet l护指向其当前数据行的光标。每调用一?nbsp;next Ҏ(gu)Q光标向下移动一行。最初它位于W一行之前,因此W一ơ调?nbsp;next 把光标|于W一行上Q它成为当前行。随着每次调用 next D光标向下Ud一行,按照从上至下的次序获?nbsp;ResultSet 行?

?nbsp;ResultSet 对象或其父辈 Statement 对象关闭之前Q光标一直保持有效?

?nbsp;SQL 中,l果表的光标是有名字的。如果数据库允许定位更新或定位删除,则需要将光标的名字作为参数提供给更新或删除命令。可通过调用Ҏ(gu) getCursorName 获得光标名?

注意Q不是所有的 DBMS 都支持定位更新和删除。可使用 DatabaseMetaData.supportsPositionedDelete ?nbsp;supportsPositionedUpdate Ҏ(gu)来检查特定连接是否支持这些操作。当支持q些操作ӞDBMS/驱动E序必须保适当锁定选定行,以定位更新不会(x)D更新异常或其它ƈ发问题?


5.1.2 ?
Ҏ(gu) getXXX 提供?jin)获取当前行中某列值的途径。在每一行内Q可按Q何次序获取列倹{但Z(jin)保证可移植性,应该从左臛_获取列|q且一ơ性地d列倹{?

列名或列号可用于标识要从中获取数据的列。例如,如果 ResultSet 对象 rs 的第二列名ؓ(f)“title”,q将值存储ؓ(f)字符Ԍ则下列Q一代码获取存储在该列中的|(x) 

String s = rs.getString("title");
String s = rs.getString(2);

注意列是从左臛_~号的,q且从列 1 开始。同Ӟ用作 getXXX Ҏ(gu)的输入的列名不区分大写?

提供使用列名q个选项的目的是Z(jin)让在查询中指定列名的用户可用相同的名字作ؓ(f) getXXX Ҏ(gu)的参数。另一斚wQ如?nbsp;select 语句未指定列名(例如在“select * from table1”中或列是导出的Ӟ(j)Q则应该使用列号。这些情况下Q用户将无法切知道列名?

有些情况下,SQL 查询q回的结果集中可能有多个列具有相同的名字。如果列名用?nbsp;getXXX Ҏ(gu)的参敎ͼ?nbsp;getXXX 返回第一个匹配列名的倹{因而,如果多个列具有相同的名字Q则需要用列索引来确保检索了(jin)正确的列倹{这Ӟ使用列号效率要稍微高一些?

关于 ResultSet 中列的信息,可通过调用Ҏ(gu) ResultSet.getMetaData 得到。返回的 ResultSetMetaData 对象给出其 ResultSet 对象各列的编受类型和属性?

如果列名已知Q但不知其烦(ch)引,则可用方?nbsp;findColumn 得到其列受?


5.1.3 数据cd和{?
对于 getXXX Ҏ(gu)QJDBC 驱动E序试图基本数据{换成指定 Java cdQ然后返回适合?nbsp;Java 倹{例如,如果 getXXX Ҏ(gu)?nbsp;getStringQ而基本数据库中数据类型ؓ(f) VARCHARQ则 JDBC 驱动E序把 VARCHAR 转换?nbsp;Java String。getString 的返回值将?nbsp;Java String 对象?

下表昄?jin)允许?nbsp;getXXX 获取?nbsp;JDBC cd?qing)推荐用它获取?nbsp;JDBC cdQ通用 SQL cdQ。小写的 x 表示允许 getXXX Ҏ(gu)获取该数据类型;大写?nbsp;X 表示对该数据cd推荐使用 getXXX Ҏ(gu)。例如,除了(jin) getBytes ?nbsp;getBinaryStream 之外的Q?nbsp;getXXX Ҏ(gu)都可用来获取 LONGVARCHAR |但是推荐Ҏ(gu)q回的数据类型?nbsp;getAsciiStream ?nbsp;getUnicodeStream Ҏ(gu)。方?nbsp;getObject Q何数据类型返回ؓ(f) Java Object。当基本数据cd是特定于数据库的抽象cd或当通用应用E序需要接受Q何数据类型时Q它是非常有用的?

可?nbsp;ResultSet.getXXX Ҏ(gu)获取常见?nbsp;JDBC 数据cd?nbsp;


5.1.4 寚w常大的行g用流
ResultSet 可以获取L大的 LONGVARBINARY ?nbsp;LONGVARCHAR 数据。方?nbsp;getBytes ?nbsp;getString 数据返回ؓ(f)大的块(最大ؓ(f) Statement.getMaxFieldSize 的返回|(j)。但是,以较?yu)的固定块获取非常大的数据可能?x)更方便,而这可通过?nbsp;ResultSet c返?nbsp;java.io.Input 来完成。从该流中可分块d数据。注意:(x)必须立即讉Kq些,因ؓ(f)在下一ơ对 ResultSet 调用 getXXX 时它们将自动关闭Q这是由于基本实现对大块数据讉K有限Ӟ(j)?nbsp;

JDBC API h三个获取的Ҏ(gu)Q分别具有不同的q回|(x) 


getBinaryStream q回只提供数据库原字节而不q行M转换的流?


getAsciiStream q回提供单字?nbsp;ASCII 字符的流?


getUnicodeStream q回提供双字?nbsp;Unicode 字符的流?


注意Q它不同?nbsp;Java ,后者返回无cd字节q可Q例如)(j)通用?nbsp;ASCII ?nbsp;Unicode 字符?

下列代码演示?nbsp;getAsciiStream 的用法:(x) 

java.sql.Statement stmt = con.createStatement();
ResultSet r = stmt.executeQuery("SELECT x FROM Table2");
// 现在?nbsp;4K 块大获取列 1 l果Q?
byte buff = new byte[4096];
while (r.next()) {
Java.io.InputStream fin = r.getAsciiStream(1);
for (;;) {
int size = fin.read(buff);
if (size == -1) { // 到达末?
break;
}
// 新填充的缓冲区发送到 ASCII 输出:(x)
output.write(buff, 0, size);
}
}

5.1.5 NULL l果?
要确定给定结果值是否是 JDBC NULLQ必dd该列Q然后?nbsp;ResultSet.wasNull Ҏ(gu)(g)查该ơ读取是否返?nbsp;JDBC NULL?

当?nbsp;ResultSet.getXXX Ҏ(gu)d JDBC NULL ӞҎ(gu) wasNull 返回下列g一Q?nbsp;


Java null |(x)对于q回 Java 对象?nbsp;getXXX Ҏ(gu)Q例?nbsp;getString、getBigDecimal、getBytes、getDate、getTime、getTimestamp、getAsciiStream、getUnicodeStream、getBinaryStream、getObject {)(j)?


零|(x)对于 getByte、getShort、getInt、getLong、getFloat ?nbsp;getDouble?


false |(x)对于 getBoolean?


5.1.6 可选结果集或多l果?
通常使用 executeQueryQ它q回单个 ResultSetQ或 executeUpdateQ它可用于Q何数据库修改语句Qƈq回更新行数Q可执行 SQL 语句。但有些情况下,应用E序在执行语句之前不知道该语句是否返回结果集。此外,有些已存储过E可能返回几个不同的l果集和/或更新计数?

Z(jin)适应q些情况QJDBC 提供?jin)一U机Ӟ允许应用E序执行语句Q然后处理由l果集和更新计数l成的Q意集合。这U机制的原理是首先调用一个完全通用?nbsp;execute Ҏ(gu)Q然后调用另外三个方法,getResultSet、getUpdateCount ?nbsp;getMoreResults。这些方法允许应用程序一ơ一个地研究语句l果Qƈ定l定l果?nbsp;ResultSet q是更新计数?

用户不必关闭 ResultSetQ当产生它的 Statement 关闭、重新执行或用于从多l果序列中获取下一个结果时Q该 ResultSet 被 Statement 自动关闭?

PS@JAVA 2005-08-05 10:16 发表评论
]]>
JDBC 指南QDriverManagerhttp://www.aygfsteel.com/shuqinpeng/articles/9365.htmlPS@JAVAPS@JAVAFri, 05 Aug 2005 02:12:00 GMThttp://www.aygfsteel.com/shuqinpeng/articles/9365.htmlhttp://www.aygfsteel.com/shuqinpeng/comments/9365.htmlhttp://www.aygfsteel.com/shuqinpeng/articles/9365.html#Feedback0http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9365.htmlhttp://www.aygfsteel.com/shuqinpeng/services/trackbacks/9365.html3.1 概述
DriverManager cL JDBC 的管理层Q作用于用户和驱动程序之间?
它跟t可用的驱动E序Qƈ在数据库和相应驱动程序之间徏立连接?
另外QDriverManager cM处理诸如驱动E序d旉限制?qing)登录和跟踪消息的显C等事务?

对于单的应用E序Q一般程序员需要在此类中直接用的唯一Ҏ(gu)?nbsp;DriverManager.getConnection。正如名U所C,该方法将建立与数据库的连接。JDBC 允许用户调用 DriverManager 的方法getDriver、getDrivers ?nbsp;registerDriver ?nbsp;Driver 的方法connect。但多数情况下,?nbsp;DriverManager cȝ理徏立连接的l节Z{?


3.1.1 跟踪可用驱动E序
DriverManager cd含一?nbsp;Driver c,它们已通过调用Ҏ(gu) DriverManager.registerDriver 对自p行了(jin)注册。所?nbsp;Driverc都必须包含有一个静(rn)态部分。它创徏该类的实例,然后在加载该实例?nbsp;DriverManager c进行注册。这P用户正常情况下将不会(x)直接调用 DriverManager.registerDriverQ而是在加载驱动程序时由驱动程序自动调用。加?nbsp;Driver c,然后自动?nbsp;DriverManager
中注册的方式有两U:(x) 


通过调用Ҏ(gu) Class.forName。这显式地加蝲驱动E序cR由于这与外部设|无养I因此推荐使用q种加蝲驱动E序的方法。以下代码加载类 acme.db.DriverQ?nbsp;
Class.forName("acme.db.Driver");

如果?nbsp;acme.db.Driver ~写为加载时创徏实例Qƈ调用以该实例为参数的DriverManager.registerDriverQ本该如此)(j)Q则它在DriverManager 的驱动程序列表中Qƈ可用于创接?


通过驱动程序添加到 java.lang.System 的属?nbsp;jdbc.drivers 中这是一个由 DriverManager cd载的驱动E序cd的列表,由冒号分隔:(x)初始?nbsp;DriverManager cLQ它搜烦(ch)pȝ属?nbsp;jdbc.driversQ?
如果用户已输入了(jin)一个或多个驱动E序Q则 DriverManager cd试图加蝲它们?
以下代码说明E序员如何在 ~/.hotjava/properties 中输入三个驱动程序类Q启动时QHotJava 把它加载到pȝ属性列表中Q:(x) 
jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.test.ourDriver;

?nbsp;DriverManager Ҏ(gu)的第一ơ调用将自动加蝲q些驱动E序cR?

注意Q加载驱动程序的W二U方法需要持久的预设环境。如果对q一点不能保证,则调用方?nbsp;Class.forName 昑ּ地加载每个驱动程序就昑־更ؓ(f)安全。这也是引入特定驱动E序的方法,因ؓ(f)一?nbsp;DriverManager c被初始化,它将不再(g)查jdbc.drivers 属性列表?

在以上两U情况中Q新加蝲?nbsp;Driver c都要通过调用 DriverManager.registerDriverc进行自我注册。如上所qͼ加蝲cL自动执行这一q程?

׃安全斚w的原因,JDBC 理层将跟踪哪个cd载器提供哪个驱动E序。这P?nbsp;DriverManager cL开q接Ӟ它仅使用本地文gpȝ或与发出q接h的代码相同的cd载器提供的驱动程序?


3.1.2 建立q接
加蝲 Driver cdƈ?nbsp;DriverManager cM注册后,它们卛_用来与数据库建立q接。当调用DriverManager.getConnection Ҏ(gu)发出q接hӞDriverManager 检查每个驱动程序,查看它是否可以徏立连接?

有时可能有多?nbsp;JDBC 驱动E序可以与给定的 URL q接。例如,与给定远E数据库q接Ӟ可以使用 JDBC-ODBC 桥驱动程序、JDBC 到通用|络协议驱动E序或数据库厂商提供的驱动程序。在q种情况下测试驱动程序的序臛_重要Q因?nbsp;DriverManager 用它所扑ֈ的第一个可以成功连接到l定 URL 的驱动程序?

首先 DriverManager 试图按注册的序使用每个驱动E序Qjdbc.drivers 中列出的驱动E序L先注册)(j)。它?yu)蟩q代码不可信ȝ驱动E序Q除非加载它们的源与试图打开q接的代码的源相同?

它通过轮流在每个驱动程序上调用Ҏ(gu) Driver.connectQƈ向它们传递用户开始传递给Ҏ(gu)DriverManager.getConnection ?nbsp;URL 来对驱动E序q行试Q然后连接第一个认?gu)?nbsp;URL 的驱动程序?

q种Ҏ(gu)初看h效率不高Q但׃不可能同时加载数十个驱动E序Q因此每ơ连接实际只需几个q程调用和字W串比较?

以下代码是通常情况下用驱动E序Q例?nbsp;JDBC-ODBC 桥驱动程序)(j)建立q接所需所有步骤的CZQ?nbsp;

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加蝲驱动E序
String url = "jdbc:odbc:fred";
DriverManager.getConnection(url, "userID", "passwd");

PS@JAVA 2005-08-05 10:12 发表评论
]]>
JDBC 指南Q连?/title><link>http://www.aygfsteel.com/shuqinpeng/articles/9364.html</link><dc:creator>PS@JAVA</dc:creator><author>PS@JAVA</author><pubDate>Fri, 05 Aug 2005 02:11:00 GMT</pubDate><guid>http://www.aygfsteel.com/shuqinpeng/articles/9364.html</guid><wfw:comment>http://www.aygfsteel.com/shuqinpeng/comments/9364.html</wfw:comment><comments>http://www.aygfsteel.com/shuqinpeng/articles/9364.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9364.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/shuqinpeng/services/trackbacks/9364.html</trackback:ping><description><![CDATA[    内容: 2 - q接本概q是从《JDBCTM Database Access from JavaTM: A Tutorial <BR>and Annotated Reference 》这本书中摘引来的。JavaSoft 目前正在准备q本书。这本书是一本教E,同时也是 JDBC 的重要参考手册,它将作ؓ(f) Java pd的组成部份在 1997 q春季由 Addison-Wesley 出版公司出版?<BR>2.1 概述 <BR>Connection 对象代表与数据库的连接。连接过E包括所执行?nbsp;SQL 语句和在该连接上所q回的结果。一个应用程序可与单个数据库有一个或多个q接Q或者可与许多数据库有连接?<BR>2.1.1 打开q接与数据库建立q接的标准方法是调用 DriverManager.getConnection <BR>Ҏ(gu)。该Ҏ(gu)接受含有某个 URL 的字W串。DriverManager c(x谓的 JDBC 理层)(j)尝试找到可与那?nbsp;URL 所代表的数据库q行q接的驱动程序。DriverManager cd有已注册?nbsp;Driver cȝ清单。当调用Ҏ(gu) getConnection Ӟ它将(g)查清单中的每个驱动程序,直到扑ֈ可与 URL 中指定的数据库进行连接的驱动E序为止。Driver 的方?nbsp;connect 使用q个 URL 来徏立实际的q接?<BR>用户可绕q?nbsp;JDBC 理层直接调?nbsp;Driver Ҏ(gu)。这在以下特D情况下很有用Q当两个驱动器可同时q接到数据库中,而用户需要明地选用其中特定的驱动器。但一般情况下Q让 DriverManager cd理打开q接q种事将更ؓ(f)单?<BR>下述代码昄如何打开一个与位于 URL "jdbc:odbc:wombat" 的数据库的连接。所用的用户标识Wؓ(f) "oboy" Q口令ؓ(f) "12Java"Q?nbsp; <BR>String url = "jdbc:odbc:wombat"; <BR>Connection con = DriverManager.getConnection(url, "oboy", "12Java"); <BR>2.1.2 一般用法的 URL׃ URL 常引h؜淆,我们先对一?nbsp;URL 作简单说明,然后再讨?nbsp;JDBC URL?<BR>URLQ统一资源定位W)(j)提供?nbsp;Internet 上定位资源所需的信息。可它惌Z个地址?<BR>URL 的第一部䆾指定?jin)访问信息所用的协议Q后面L跟着冒号。常用的协议?nbsp;"ftp"Q代表“文件传输协议”)(j)?nbsp;"http" Q代表“超文本传输协议”)(j)?<BR>如果协议?nbsp;"file"Q表C源是在某个本地文件系l上而非?nbsp;Internet 上(下例用于表示我们所描述的部分;它ƈ?nbsp;URL 的组成部分)(j)?<BR>ftp://javasoft.com/docs/JDK-1_apidocs.zip <BR>http://java.sun.com/products/jdk/CurrentRelease <BR>file:/home/haroldw/docs/books/tutorial/summary.html <BR>URL 的其余部份(冒号后面的)(j)l出?jin)数据资源所处位|的有关信息。如果协议是 fileQ则 URL 的其余部份是文g的\径。对?nbsp;ftp ?nbsp;http 协议QURL 的其余部份标识了(jin)Lq可选地l出某个更详的地址路径。例如,以下?nbsp;JavaSoft 主页?nbsp;URL。该 URL 只标识了(jin)LQ?nbsp; <BR>http://java.sun.com从该主页开始浏览,可以进到许多其它的|页中,其中之一是 <BR>JDBC 主页。JDBC 主页?nbsp;URL 更ؓ(f)具体Q它看v来类|(x) http://java.sun.com/products/jdbc <BR>2.1.3 JDBC URL JDBC URL 提供?jin)一U标识数据库的方法,可以使相应的驱动E序能识别该数据库ƈ与之建立q接。实际上Q驱动程序编E员决定用什?nbsp;JDBC URL 来标识特定的驱动E序。用户不必关?j)如何来形?nbsp;JDBC URLQ他们只M用与所用的驱动E序一h供的 URL 卛_。JDBC 的作用是提供某些U定Q驱动程序编E员在构造他们的 JDBC URL 时应该遵循这些约定?<BR>׃ JDBC URL 要与各种不同的驱动程序一起用,因此q些U定应非常灵zR首先,它们应允怸同的驱动E序使用不同的方案来命名数据库。例如, odbc 子协议允许(但ƈ不是要求Q?nbsp;URL 含有属性倹{第二,JDBC URL 应允?dng)R动程序编E员一切所需的信息编入其中。这样就可以让要与给定数据库对话?nbsp;applet 打开数据库连接,而无要求用户去做Q何系l管理工作?<BR>W三Q?nbsp;JDBC URL 应允许某U程度的间接性。也是_(d)JDBC URL 可指向逻辑L或数据库名,而这U逻辑L或数据库名将ql命名系l动态地转换为实际的名称。这可以使系l管理员不必特定主机声明ؓ(f) JDBC 名称的一部䆾。网l命名服务(例如 DNS?nbsp;NIS ?nbsp;DCE Q有多种,而对于用哪U命名服务ƈ无限制。JDBC URL 的标准语法如下所C。它׃部分l成Q各部分间用冒号分隔Q?nbsp; <BR>jdbc:< 子协?nbsp;>:< 子名U?nbsp;>JDBC URL 的三个部分可分解如下Q?nbsp;jdbc ─ 协议。JDBC URL 中的协议L jdbc?<BR><子协?gt; ─ 驱动E序名或数据库连接机Ӟq种机制可由一个或多个驱动E序支持Q的名称。子协议名的典型CZ?nbsp;"odbc"Q该名称是ؓ(f)用于指定 ODBC 风格的数据资源名U的 URL 专门保留的。例如,Z(jin)通过 JDBC-ODBC 桥来讉K某个数据库,可以用如下所C的 URLQ?nbsp; <BR>jdbc:odbc:fred本例中,子协议ؓ(f) "odbc"Q子名称 "fred" 是本地ODBC 数据资源?<BR>如果要用|络命名服务Q这?nbsp;JDBC URL 中的数据库名UC必是实际名称Q,则命名服务可以作为子协议。例如,可用如下所C的 URL Q?nbsp; <BR>jdbc:dcenaming:accounts-payable本例中,?nbsp;URL 指定?jin)本?nbsp;DCE 命名服务应该?<BR>数据库名U?nbsp;"accounts-payable" 解析为更为具体的可用于连接真实数据库的名U?lt;子名U?gt; ─ 一U标识数据库的方法。子名称可以依不同的子协议?<BR>变化。它q可以有子名U的子名Uͼ含有驱动E序~程员所选的M内部语法Q。用子名称的目的是为定位数据库提供_的信息。前 <BR>例中Q因?nbsp;ODBC 提供其余部份的信息Q因此用 "fred" 已_。然而,位于q程服务器上的数据库需要更多的信息。例如,如果数据库是通过 Internet 来访问的Q则?nbsp;JDBC URL 中应网l地址作ؓ(f)子名U的一部䆾包括q去Q且必须遵@如下所C的标准 URL 命名U定Q?nbsp; <BR>//L?端口/子协议假?nbsp;"dbnet" 是个用于某个主接到 Internet 上的协议Q则 JDBC URL cMQ?<BR>jdbc:dbnet://wombat:356/fred 2.1.4 "odbc" 子协?<BR>子协?nbsp;odbc 是一U特D情c(din)它是ؓ(f)用于指定 ODBC 风格的数据资源名U的 URL 而保留的Qƈh下列Ҏ(gu):(x)允许在子名称Q数据资源名Uͼ(j)后面指定L多个属性倹{odbc 子协议的完整语法为:(x) jdbc:odbc:< 数据资源名称 >[;< 属性名 >=< 属性?nbsp;>]*因此Q以下都是合法的 jdbc:odbc 名称Q?nbsp;jdbc:odbc:qeor7jdbc:odbc:wombat <BR>jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER <BR>jdbc:odbc:qeora;UID=kgh;PWD=fooey2.1.5 注册子协议驱动程序编E员可保留某个名UC之用作 JDBC URL 的子协议名?<BR>?nbsp;DriverManager cd此名U加到已注册的驱动程序清单中ӞZ保留该名U的驱动E序应能识别该名Uƈ与它所标识的数据库建立q接。例如,odbc 是ؓ(f) JDBC- ODBC 桥而保留的。示例之二,假设有个 Miracle 公司Q它可能?x)?nbsp;"miracle" 注册接到?nbsp;Miracle DBMS 上的 JDBC 驱动E序的子协议Q从而其他人都无法使用q个名称。JavaSoft 目前作ؓ(f)非正式代理负责注?nbsp;JDBC 子协议名U。要注册某个子协议名Uͼ请发送电(sh)子邮件到下述地址Q?nbsp; <BR>jdbc@wombat.eng.sun.com2.1.6 发?nbsp;SQL 语句q接一旦徏立,可用来向它所涉及(qing)的数据库传?nbsp;SQL 语句。JDBC对可被发送的 SQL 语句cd不加M限制。这提供了(jin)很大的灵zL,卛_怋用特定的数据库语句或甚至于非 SQL 语句。然而,它要 <BR>求用戯p责确保所涉及(qing)的数据库可以处理所发送的 SQL 语句Q否则将自食其果。例如,如果某个应用E序试图向不支持储存E序?nbsp;DBMS 发送储存程序调用,׃(x)p|q将抛出异常。JDBC 要求驱动E序应至能提供 ANSI SQL-2 Entry Level 功能才可是W合 JDBC 标准TM 的。这意味着用户臛_可信赖这一标准U别的功能。JDBC 提供?jin)三个类Q用于向数据库发?nbsp;SQL 语句。Connection 接口中的三个Ҏ(gu)可用于创些类的实例。下面列?gu)些类及(qing)其创徏?gu)Q?nbsp; <BR>Statement ─ 由方?nbsp;createStatement 所创徏。Statement 对象用于发送简单的 SQL 语句?nbsp; <BR>PreparedStatement ─ 由方?nbsp;prepareStatement 所创徏?<BR>PreparedStatement 对象用于发送带有一个或多个输入参数Q?nbsp;IN 参数Q?<BR>?nbsp;SQL 语句。PreparedStatement 拥有一l方法,用于讄 IN 参数的倹{?<BR>执行语句Ӟq些 IN 参数被送到数据库中。PreparedStatement 的实 <BR>例扩展了(jin) Statement Q因此它们都包括?nbsp;Statement 的方法?<BR>PreparedStatement 对象有可能比 Statement 对象的效率更高,因ؓ(f)它已被预~译qƈ存放在那以供来使用?nbsp; <BR>CallableStatement ─ 由方?nbsp;prepareCall 所创徏。CallableStatement 对象 <BR>用于执行 SQL 储存E序 ─ 一l可通过名称来调用(p函数的调用那P(j)?<BR>SQL 语句。CallableStatement 对象?nbsp;PreparedStatement 中承了(jin)用于 <BR>处理 IN 参数的方法,而且q增加了(jin)用于处理 OUT 参数?nbsp;INOUT 参数的方法?nbsp; <BR>以下所列提供的Ҏ(gu)可以快速决定应用哪?nbsp;Connection Ҏ(gu)来创Z同类型的 SQL 语句Q?nbsp;createStatement Ҏ(gu)用于Q?<BR>单的 SQL 语句Q不带参敎ͼ(j) prepareStatement Ҏ(gu)用于Q?nbsp;带一个或多个 IN 参数?nbsp;SQL 语句 l常被执行的?nbsp;SQL 语句 <BR>prepareCall Ҏ(gu)用于Q?nbsp;调用已储存过E?.1.7 事务事务׃个或多个q样的语句组成:(x)q些语句已被执行、完成ƈ被提交或q原。当调用Ҏ(gu) commit ?nbsp;rollback Ӟ当前事务卛_q束,另一个事务随卛_始?<BR>~省情况下,新连接将处于自动提交模式。也是_(d)当执行完语句后,自动对那个语句调用 commit Ҏ(gu)。这U情况下Q由于每个语句都是被单独提交的,因此一个事务只׃个语句组成。如果禁用自动提交模式,事务要{到 commit ?nbsp;llback Ҏ(gu)被显式调用时 <BR>才结束,因此它将包括上一ơ调?nbsp;commit ?nbsp;rollback Ҏ(gu)以来所有执行过的语句。对于第二种情况Q事务中的所有语句将作ؓ(f)l来提交或还原。方?nbsp;commit ?nbsp;SQL 语句Ҏ(gu)据库所做的M更改成ؓ(f)怹性的Q它q将释放事务持有的全部锁。而方?nbsp;rollback 弃去那些更攏V?<BR>有时用户在另一个更改生效前不想让此更改生效。这可通过用自动提交q将两个更新l合在一个事务中来达到。如果两个更新都是成?<BR>Q则调用 commit Ҏ(gu)Q从而两个更新l果成ؓ(f)怹性的Q如果其中之一或两个更新都p|?jin),则调?nbsp;rollback Ҏ(gu)Q以值恢复ؓ(f)q行更新之前的倹{?<BR>大多?nbsp;JDBC 驱动E序都支持事务。事实上Q符?nbsp;JDBC 的驱动程序必L持事务。DatabaseMetaData l出的信息描q?nbsp;DBMS 所提供的事务支持水q?.1.8 事务隔离U别如果 DBMS 支持事务处理Q它必须有某U途径来管理两个事务同时对一个数据库q行操作时可能发生的冲突。用户可指定事务隔离U别Q以指明 DBMS 应该花多大精力来解决潜在冲突。例如,当事务更改了(jin)某个D第二个事务却在该更改被提交或还原前d该值时该怎么?nbsp;假设W一个事务被q原后,W二个事务所d的更改值将是无效的Q那么是否可允许q种冲突Q?nbsp;JDBC 用户可用以下代码来指C?nbsp;DBMS 允许在D提交前读取该|“dirty d”)(j)Q其?nbsp;con 是当前连接:(x)  <BR>con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); <BR>事务隔离U别高Qؓ(f)避免冲突所q_֊也就多。Connection 接口定义?jin)五U,其中最低别指定了(jin)Ҏ(gu)׃支持事务Q而最高别则指定当事务在Ҏ(gu)个数据库q行操作ӞM其它事务不得寚w个事务正在读取的数据q行M更改。通常Q隔ȝ别越高,应用E序执行的速度也就慢Q由于用于锁定的资源耗费增加?jin),而用户间的ƈ发操作减了(jin)Q。在军_采用什么隔ȝ别时Q开发h员必d性能需求和数据一致性需求之间进行权衡。当?dng)实际所能支持的U别取决于所涉及(qing)?nbsp;DBMS 的功能?<BR>当创?nbsp;Connection 对象Ӟ其事务隔ȝ别取决于驱动E序Q但通常是所涉及(qing)的数据库的缺省倹{用户可通过调用 setIsolationLevelҎ(gu)来更改事务隔ȝ别。新的别将在该q接q程的剩余时间内生效。要惛_改变一个事务的事务隔离U别Q必d该事务开始前q行讄Qƈ在该事务l束后进行复位。我们不提倡在事务的中途对事务隔离U别q行更改Q因立卌?nbsp;commit Ҏ(gu)的调用,使在此之前所作的M更改变成怹性的?img src ="http://www.aygfsteel.com/shuqinpeng/aggbug/9364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/shuqinpeng/" target="_blank">PS@JAVA</a> 2005-08-05 10:11 <a href="http://www.aygfsteel.com/shuqinpeng/articles/9364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC 指南Q介l?/title><link>http://www.aygfsteel.com/shuqinpeng/articles/9363.html</link><dc:creator>PS@JAVA</dc:creator><author>PS@JAVA</author><pubDate>Fri, 05 Aug 2005 02:10:00 GMT</pubDate><guid>http://www.aygfsteel.com/shuqinpeng/articles/9363.html</guid><wfw:comment>http://www.aygfsteel.com/shuqinpeng/comments/9363.html</wfw:comment><comments>http://www.aygfsteel.com/shuqinpeng/articles/9363.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/shuqinpeng/comments/commentRss/9363.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/shuqinpeng/services/trackbacks/9363.html</trackback:ping><description><![CDATA[    本简介是从《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》这本书中摘引来的?<BR>JavaSoft 目前正在准备q本书。这是一本教E,同时也是 JDBC 的重要参考手册,它将作ؓ(f) Java pd的组成部份在 1997 q春季由 Addison-Wesley 出版公司出版?nbsp; <BR><BR><BR>1.1 什么是 JDBCTMQ?nbsp; <BR>JDBCTM 是一U用于执?nbsp;SQL 语句?nbsp;JavaTM APIQ有意思的是,JDBC 本n是个商标名而不是一个羃写字Q然而,JDBC 常被认ؓ(f)是代?nbsp;“Java 数据库连?nbsp;(Java Database Connectivity)”)(j)。它׃l用 Java ~程语言~写的类和接口组成。JDBC 为工?数据库开发h员提供了(jin)一个标准的 APIQ他们能够用纯 Java API 来编写数据库应用E序?nbsp; <BR><BR>有了(jin) JDBCQ向各种关系数据库发?nbsp;SQL 语句是一件很Ҏ(gu)的事。换a之,有了(jin) JDBC APIQ就不必?nbsp;Sybase 数据库专门写一个程序,?nbsp;Oracle 数据库又专门写一个程序,?nbsp;Informix 数据库又写另一个程序,{等。?zhn)只需?nbsp;JDBC API 写一个程序就够了(jin)Q它可向相应数据库发?nbsp;SQL 语句。而且Q?nbsp;Java ~程语言~写的应用程序,无d忧虑要ؓ(f)不同的^台编写不同的应用E序。将 Java ?nbsp;JDBC l合hɽE序员只d一遍程序就可让它在Mq_上运行?nbsp; <BR><BR>Java h坚固、安全、易于用、易于理解和可从|络上自动下载等Ҏ(gu),是编写数据库应用E序的杰?gu)a。所需要的只是 Java 应用E序与各U不同数据库之间q行对话的方法。?nbsp;JDBC 正是作ؓ(f)此种用途的机制?nbsp; <BR><BR>JDBC 扩展?nbsp;Java 的功能。例如,?nbsp;Java ?nbsp;JDBC API 可以发布含有 applet 的网,而该 applet 使用的信息可能来自远E数据库。企业也可以?nbsp;JDBC 通过 Intranet 所有职员连C个或多个内部数据库中Q即使这些职员所用的计算机有 Windows?nbsp;Macintosh ?nbsp;UNIX {各U不同的操作pȝQ。随着来多的程序员开始?nbsp;Java ~程语言Q对?nbsp;Java中便捷地讉K数据库的要求也在日益增加?nbsp; <BR><BR>MIS 理员们都喜?nbsp;Java ?nbsp;JDBC 的结合,因ؓ(f)它信息传播变得Ҏ(gu)和经。企业可l箋使用它们安装好的数据库,q能便捷地存取信息,即ɘq些信息是储存在不同数据库管理系l上。新E序的开发期很短。安装和版本控制大为简化。程序员可只~写一遍应用程序或只更Cơ,然后它攑ֈ服务器上Q随后Q何h都可得到最新版本的应用E序。对于商务上的销售信息服务, Java ?nbsp;JDBC 可ؓ(f)外部客户提供获取信息更新的更好方法?nbsp; <BR><BR><BR>1.1.1 JDBC 的用途是什么?  <BR>单地_(d)JDBC 可做三g事:(x)  <BR><BR><BR><BR>与数据库建立q接Q?nbsp; <BR>发?nbsp;SQL 语句Q?nbsp; <BR>处理l果?nbsp; <BR><BR><BR>下列代码D늻Z(jin)以上三步的基本示例:(x)  <BR><BR>Connection con = DriverManager.getConnection (  <BR>"jdbc:odbc:wombat", "login", "password");  <BR>Statement stmt = con.createStatement();  <BR>ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");  <BR>while (rs.next()) {  <BR>int x = rs.getInt("a");  <BR>String s = rs.getString("b");  <BR>float f = rs.getFloat("c");  <BR>}  <BR><BR><BR>1.1.2 JDBC 是一U低U?nbsp;API Q是高 API 的基  <BR>JDBC 是个“低U”接口,也就是说Q它用于直接调用 SQL 命o(h)。在q方面它的功能极佻Iq比其它的数据库q接 API 易于使用Q但它同时也被设计ؓ(f)一U基接口Q在它之上可以徏立高U接口和工具。高U接口是“对用户友好的”接口,它用的是一U更易理解和更ؓ(f)方便?nbsp;APIQ这U?nbsp;API 在幕后被转换?nbsp;JDBC q样的低U接口。在~写本文Ӟ正在开发两U基?nbsp;JDBC 的高U?nbsp;APIQ?nbsp; <BR><BR><BR>一U用?nbsp;Java 的嵌入式 SQL。至已l有一个提供者计划编写它。DBMS 实现 SQLQ一U专门设计来与数据库联合使用的语a。JDBC 要求 SQL 语句必须作ؓ(f) String 传给 Java Ҏ(gu)。相反,嵌入?nbsp;SQL 预处理器允许E序员将 SQL 语句直接与Java 混在一起用。例如,可在 SQL 语句中?nbsp;Java 变量Q用以接受或提供 SQL 倹{然后,嵌入?nbsp;SQL 预处理器通过 JDBC 调用把这U?nbsp;Java/SQL 的؜合物转换?nbsp;Java?nbsp; <BR>关系数据库表?nbsp;Java cȝ直接映射。JavaSoft 和其它提供者都声称要实现该 API。在q种“对?关系”映中Q表中的每行对应于类的一个实例,而每列的值对应于该实例的一个属性。于是,E序员可直接?nbsp;Java 对象q行操作Q存取数据所需?nbsp;SQL 调用在“掩盖下”自动生成。此外还可提供更复杂的映,例如多个表中的行结合进一?nbsp;Java cM?nbsp; <BR>随着Z?nbsp;JDBC 的兴日益增涨,来多的开发h员一直在使用Z JDBC 的工P以ɽE序的编写更加容易。程序员也一直在~写力图使最l用户对数据库的讉K变得更ؓ(f)单的应用E序。例如,应用E序可提供一个选择数据库Q务的菜单?<BR>d被选定后,应用E序给出提C及(qing)I白供填写执行选定d所需的信息。所需信息输入后,应用E序自动调用所需的SQL 命o(h)。在q样一U程序的协助下,即用户Ҏ(gu)不懂 SQL 的语法,也可以执行数据库d?nbsp; <BR><BR><BR>1.1.3 JDBC ?nbsp;ODBC 和其?nbsp;API 的比?nbsp; <BR>目前QMicrosoft ?nbsp;ODBCQ开攑ּ数据库连接)(j)API 可能是用最q的、用于访问关pL据库的编E接口。它能在几乎所有^Cq接几乎所有的数据库。ؓ(f)什?nbsp;Java 不?nbsp;ODBCQ?nbsp; <BR><BR>对这个问题的回答是:(x)Java 可以使用 ODBCQ但最好是?nbsp;JDBC 的帮助下?nbsp;JDBC-ODBC 桥的形式使用Q这一Ҏ(gu)们稍后再说。现在的问题已变成:(x)“ؓ(f)什么需?nbsp;JDBC”? 回答如下Q?nbsp; <BR><BR><BR>ODBC 不适合直接?nbsp;Java 中用,因ؓ(f)它?nbsp;C 语言接口。从 Java 调用本地 C 代码在安全性、实现、坚固性和E序的自动移植性方面都有许多缺炏V?nbsp; <BR>?nbsp;ODBC C API ?nbsp;Java API 的字面翻译是不可取的。例如,Java 没有指针Q?nbsp;ODBC 却对指针用得很广泛(包括很容易出错的指针 "void *"Q。?zhn)可以?nbsp;JDBC 惌成被转换为面向对象接口的 ODBCQ而面向对象的接口?nbsp;Java E序员来说较 <BR>易于接收?nbsp; <BR>ODBC 很难学。它把简单和高功能混在一P而且即对于单的查询Q其选项也极为复杂。相反,JDBC 量保证单功能的便性,而同时在必要时允怋用高U功能?nbsp; <BR>启用“纯 Java ”机刉要象 JDBC q样?nbsp;Java API。如果?nbsp;ODBCQ就必须手动地将 ODBC 驱动E序理器和驱动E序安装在每台客h上。如果完全用 Java ~写 JDBC 驱动E序?nbsp;JDBC 代码在所?nbsp;Java q_上(从网l计机到大型机Q都可以自动安装、移植ƈ保证安全性?nbsp; <BR>MQJDBC API 对于基本?nbsp;SQL 抽象和概忉|一U自然的 Java 接口。它建立?nbsp;ODBC 上而不是从零开始。因此,熟?zhn)?nbsp;ODBC 的程序员发?nbsp;JDBC 很容易用。JDBC 保留?nbsp;ODBC 的基本设计特征;事实上,两种接口都基?nbsp;X/Open SQL CLIQ调用接口Q。它们之间最大的区别在于QJDBC ?nbsp;Java 风格与优点ؓ(f)基础q进行优化,因此更加易于使用?nbsp; <BR><BR>最q,Microsoft 又引q了(jin) ODBC 之外的新 APIQ?nbsp;RDO?nbsp;ADO ?nbsp;OLE DB。这些设计在许多斚w?nbsp;JDBC 是相同的Q即它们都是面向对象的数据库接口且基于可?nbsp;ODBC 上实现的cR但在这些接口中Q我们未看见有特别的功能使我们要转而选择它们来替?nbsp;ODBCQ尤其是?nbsp;ODBC 驱动E序已徏立v较ؓ(f)完善的市(jng)场的情况下。它们最多也是?nbsp;ODBC 上加?jin)一U装饰而已。这q不是说 JDBC 不需要从其最初的版本再发展了(jin)Q然而,我们觉得大部份的新功能应归入诸如前一节中所q的对象/关系映射和嵌入式 SQL q样的高U?nbsp;API?nbsp; <BR><BR><BR>1.1.4 两层模型和三层模?nbsp; <BR>JDBC API 既支持数据库讉K的两层模型,同时也支持三层模型?nbsp; <BR><BR>在两层模型中QJava applet 或应用程序将直接与数据库q行对话。这需要一?nbsp;JDBC 驱动E序来与所讉K的特定数据库理pȝq行通讯。用L(fng) SQL 语句被送往数据库中Q而其l果被送回l用戗数据库可以位于另一台计机上,用户通过|络q接C面。这叫做客h/服务器配|,其中用户的计机为客hQ提供数据库的计机为服务器。网l可以是 IntranetQ它可将公司职员q接hQ,也可以是 Internet?nbsp; <BR><BR><BR><BR><BR><BR>在三层模型中Q命令先是被发送到服务的“中间层”,然后由它?yu)?nbsp;SQL 语句发送给数据库。数据库?nbsp;SQL 语句q行处理q将l果送回C间层Q中间层再将l果送回l用戗MIS ȝ们都发现三层模型很吸引hQ因为可用中间层来控制对公司数据的访问和可作的的更新的种cR中间层的另一个好处是Q用户可以利用易于用的高 APIQ而中间层把它{换ؓ(f)相应的低U调用。最后,许多情况下三层结构可提供一些性能上的好处?nbsp; <BR><BR><BR><BR><BR>到目前ؓ(f)止,中间层通常都用 C ?nbsp;C++ q类语言来编写,q些语言执行速度较快。然而,随着最优化~译器(它把 Java字节代码转换为高效的特定于机器的代码Q的引入Q用 Java 来实C间层变得越来越实际。这是一个很大的q步Q它使h们可以充分利?nbsp;Java 的诸多优点(如坚固、多U程和安全等特征Q。JDBC 对于?nbsp;Java 的中间层来访问数据库非常重要?nbsp; <BR><BR><BR>1.1.5 SQL 的一致?nbsp; <BR>l构化查询语a (SQL) 是访问关pL据库的标准语a。困难之处在于:(x)虽然大多数的 DBMS Q数据库理pȝQ对其基本功能都使用?jin)标准Ş式?nbsp;SQLQ但它们却不W合最qؓ(f)更高U的功能定义的标?nbsp;SQL 语法或语义。例如,q所有的数据库都支持储存E序或外部连接,那些支持q一功能的数据库又相互不一致。h们希?nbsp;SQL 中真正标准的那部份能够进行扩展以包括来多的功能。但同时 JDBC API 又必L持现有的 SQL?nbsp; <BR><BR>JDBC API 解决q个问题的一U方法是允许Q何查询字W串一直传到所涉及(qing)?nbsp;DBMS 驱动E序上。这意味着应用E序可以使用L多的 SQL 功能Q但它必dq样的风险:(x)有可能在某些 DBMS 上出错。事实上Q应用程序查询甚至不一定要?nbsp;SQLQ或者说它可以是个ؓ(f)特定?nbsp;DBMS 设计?nbsp;SQL 的专用派生物Q例如,文档或图象查询)(j)?nbsp; <BR><BR>JDBC 处理 SQL 一致性问题的W二U方法是提供 ODBC 风格的{义子句。这在 4.1.5 节“语句对象中?nbsp;SQL 转义语法”中讨论?nbsp; <BR><BR>转义语法为几个常见的 SQL 分歧提供?jin)一U标准的 JDBC 语法。例如,Ҏ(gu)期文字和已储存过E的调用都有转义语法?nbsp; <BR><BR>对于复杂的应用程序,JDBC 用第三种Ҏ(gu)来处?nbsp;SQL 的一致性问题。它利用 DatabaseMetaData 接口来提供关?nbsp;DBMS 的描q性信息,从而应用E序能适应每个 DBMS 的要求和功能?nbsp; <BR><BR>׃ JDBC API 用作开发高U数据库讉K工具?nbsp;API 的基 APIQ因此它q必L意其所有上层徏{的一致性。“符?nbsp;JDBC 标准TM" 代表用户可依赖的 JDBC 功能的标准别。要使用q一说明Q驱动程序至必L?nbsp;ANSI SQL-2 Entry LevelQANSI SQL-2 代表国国家标准局 1992 q所采用的标准。Entry Level 代表 SQL 功能的特定清单)(j)。驱动程序开发h员可?nbsp;JDBC API 所带的试工具包来定他们的驱动程序是否符合这些标准?nbsp; <BR><BR>“符?nbsp;JDBC 标准TM?nbsp;表示提供者的 JDBC 实现已经通过?nbsp;JavaSoft 提供的一致性测试。这些一致性测试将(g)?nbsp;JDBC API 中定义的所有类和方法是否都存在Qƈ可能地(g)查程序是否具?nbsp;SQL Entry Level 功能。当?dng)q些试q不完全Q而且 JavaSoft 目前也无意对各提供者的实现q行标。但q种一致性定义的可?nbsp;JDBC 实现提供一定的可信度。随着来多的数据库提供者、连接提供者、Internet 提供者和应用E序~程员对 JDBC API 的接受,JDBC 也正q速成?nbsp;Java 数据库访问的标准?nbsp; <BR><BR><BR>1.2 JDBC 产品  <BR>在编写本文时Q有几个Z JDBC 的品已开发完毕或正在开发中。当?dng)本节中的信息很快成时信息。因此,有关最新的信息Q请查阅 JDBC 的网站,可通过从以?nbsp;URL 开始浏览找刎ͼ(x)  <BR><BR>http://java.sun.com/products/jdbc  <BR><BR><BR>1.2.1 JavaSoft 框架  <BR>JavaSoft 提供三种 JDBC 产品lgQ它们是 Java 开发工具包 (JDK) 的组成部份:(x)  <BR><BR><BR>JDBC 驱动E序理器,  <BR><BR><BR>JDBC 驱动E序试工具包,?nbsp; <BR><BR><BR>JDBC-ODBC 桥?nbsp; <BR><BR><BR>JDBC 驱动E序理器是 JDBC 体系l构的支柱。它实际上很,也很单;其主要作用是?nbsp;Java 应用E序q接到正的JDBC 驱动E序上,然后即退出?nbsp; <BR><BR>JDBC 驱动E序试工具包ؓ(f)?nbsp;JDBC 驱动E序q行(zhn)的E序提供一定的可信度。只有通过 JDBC 驱动E序试包的驱动E序才被认ؓ(f)是符?nbsp;JDBC 标准TM 的?nbsp; <BR><BR>JDBC-ODBC 桥 ODBC 驱动E序可被用作 JDBC 驱动E序。它的实Cؓ(f) JDBC 的快速发展提供了(jin)一条途径Q其长远目标提供一U访问某些不常见?nbsp;DBMSQ如果对q些不常见的 DBMS 未实?nbsp;JDBCQ?nbsp;的方法?nbsp; <BR><BR><BR><BR><BR><BR>1.2.2 JDBC 驱动E序的类?nbsp; <BR>我们目前所知晓?nbsp;JDBC 驱动E序可分Z下四个种c:(x)  <BR><BR><BR>JDBC-ODBC 桥加 ODBC 驱动E序QJavaSoft 桥品利?nbsp;ODBC 驱动E序提供 JDBC 讉K。注意,必须?nbsp;ODBC 二进制代码(许多情况下还包括数据库客h代码Q加载到使用该驱动程序的每个客户Z。因此,q种cd的驱动程序最适合于企业网Q这U网l上客户机的安装不是主要问题Q,或者是?nbsp;Java ~写的三层结构的应用E序服务器代码?nbsp;本地 API - 部䆾?nbsp;Java 来编写的驱动E序Q?nbsp;q种cd的驱动程序把客户?nbsp;API 上的 JDBC 调用转换?nbsp;Oracle?nbsp;Sybase、Informix、DB2 或其?nbsp;DBMS 的调用。注意,象桥驱动E序一Pq种cd的驱动程序要求将某些二进制代码加载到每台客户Z?nbsp; <BR>JDBC |络U?nbsp;Java 驱动E序Q这U驱动程序将 JDBC 转换Z DBMS 无关的网l协议,之后q种协议又被某个服务器{换ؓ(f)一U?nbsp;DBMS 协议。这U网l服务器中间件能够将它的U?nbsp;Java 客户接到多种不同的数据库上。所用的具体协议取决于提供者。通常Q这是最为灵zȝ JDBC 驱动E序。有可能所有这U解x案的提供者都提供适合?nbsp;Intranet 用的产品。ؓ(f)?jin)ɘq些产品也支?nbsp;Internet 讉KQ它们必d?nbsp;Web 所提出的安全性、通过防火墙的讉K{方面的额外要求。几家提供者正?nbsp;JDBC 驱动E序加到他们现有的数据库中间件品中?nbsp; <BR>本地协议U?nbsp;Java 驱动E序Q这U类型的驱动E序?nbsp;JDBC 调用直接转换?nbsp;DBMS 所使用的网l协议。这允总客户机机器上直接调用 DBMS 服务器,?nbsp;Intranet 讉K的一个很实用的解x法。由于许多这L(fng)协议都是专用的,因此数据库提供者自己将是主要来源,有几家提供者已在着手做qg事了(jin)?nbsp; <BR>最后,我们预计W?nbsp;3? c驱动程序将成ؓ(f)?nbsp;JDBC 讉K数据库的首选方法。第 1? c驱动程序在直接的纯 Java 驱动E序q没有上?jng)前?x)作ؓ(f)q渡Ҏ(gu)来用。对W?nbsp;1? c驱动程序可能会(x)有一些变U(下表中未列出Q,q些变种要求有连接器Q但通常q些是更加不可取的解x案。第 3? c驱动程序提供了(jin) Java 的所有优点,包括自动安装Q例如,通过使用 JDBC 驱动E序?nbsp;applet applet来下载该驱动E序Q?nbsp; <BR><BR>下表昄?jin)?nbsp;4 U类型的驱动E序?qing)其属性:(x)  <BR><BR><BR>驱动E序U类 U?nbsp;JAVAQ?nbsp;|络协议  <BR>1 - JDBC-OCBC ?nbsp;?nbsp;直接  <BR>2 - Z本地 API ?nbsp;?nbsp;直接  <BR>3 - JDBC |络?nbsp;?nbsp;要求q接?nbsp; <BR>4 - Z本地协议?nbsp;?nbsp;直接  <BR><BR><BR><BR>1.2.3 JDBC 驱动E序的获?nbsp; <BR>在编写本文时Q已有几十个属于U类的驱动程序,卛_?nbsp;Javasoft 桥联合用的 1: ODBC 驱动E序的驱动程序。有大约十多个属于种c?nbsp;2 的驱动程序是?nbsp;DBMS 的本?nbsp;API 为基~写的。只有几个属于种c?nbsp;3 的驱动程序。目前至有 2 个属于种c?nbsp;4 的驱动程序,但到 1997 q底Q我们预计主要的 DBMS 都会(x)有种c?nbsp;4 的驱动程序?nbsp; <BR><BR>要获取关于驱动程序的最C息,h?nbsp;JDBC 的网站,其网址为:(x) http:// java.sun.com/products/jdbc。提供第 3 U驱动程序的首批提供者是 SCO、Open Horizon、Visigenic ?nbsp;WebLogic。JavaSoft 和数据库q接的领先提供?nbsp;Intersolv合作研制?nbsp;JDBC-ODBC 桥和 JDBC 驱动E序试工具包?nbsp; <BR><BR><BR>1.2.4 其它产品  <BR>各种 JDBC 应用E序的开发工h在开发中。请注意查阅 JavaSoft |页以得到更C息?nbsp;<img src ="http://www.aygfsteel.com/shuqinpeng/aggbug/9363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/shuqinpeng/" target="_blank">PS@JAVA</a> 2005-08-05 10:10 <a href="http://www.aygfsteel.com/shuqinpeng/articles/9363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">Ͻ</a>| <a href="http://" target="_blank">פ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ϲ</a>| <a href="http://" target="_blank">ɣ</a>| <a href="http://" target="_blank">Ϻӿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">߷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank">³</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ȩ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʼ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">կ</a>| <a href="http://" target="_blank">Ҵ</a>| <a href="http://" target="_blank">Ȫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">¤</a>| <a href="http://" target="_blank">Ȫ</a>| <a href="http://" target="_blank">ƫ</a>| <a href="http://" target="_blank">ױ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>