JDBC
提供三种类型的语句对象:
Statement
,
PreparedStatement
,
CallableStatement
。
其中
PreparedStatement
是
Statement
的子类,
CallableStatement
是
PreparedStatement
的子类。每一种语句对象用来运行特定类型的
SQL
语句。
Statement
对象用来运行简单类型的
SQL
语句,语句中无需指定参数。
PreparedStatement
对象用来运行包含(或不包含)
IN
类型参数的预编译
SQL
语句。
CallableStatement
对象用来调用数据库存储过程。
Statement
1.
概述
Statement
对象用于将
SQL
语句发送到数据库服务器。
2.
创建
Statement
对象
建立连接后,
Statement
对象用
Connection
对象的
createStatement
方法创建,以下代码创建
Statement
对象:
Connection con = DriverManager.getConnection(url, SYSDBA, SYSDBA);
Statement stmt = con.createStatement();
3.
使用
Statement
对象执行语句
Statement
接口提供了三种执行
SQL
语句的方法:
executeQuery
、
executeUpdate
和
execute
。
方法
executeQuery
用于产生单个结果集的语句,例如
SELECT
语句。
方法
executeUpdate
用于执行
INSERT
、
UPDATE
或
DELETE
语句以及
SQL DDL
语句,如
CREATE TABLE
和
DROP TABLE
。
INSERT
、
UPDATE
或
DELETE
语句的效果是修改表中零行或多行中的一列或多列。
executeUpdate
的返回值是一个整数,表示受影响的行数。对于
CREATE TABLE
或
DROP TABLE
等
DDL
语句,
executeUpdate
的返回值总为零。
方法
execute
用于执行返回多个结果集、多个更新元组数或二者组合的语句。
执行语句的三种方法都将关闭所调用的
Statement
对象的当前打开结果集(如果存在)。这意味着在重新执行
Statement
对象之前,需要完成对当前
ResultSet
对象的处理。
4.
关闭
Statement
对象
Statement
对象可由
Java
垃圾收集程序自动关闭。但作为一种好的编程风格,应在不需要
Statement
对象时显式地关闭它们。这将立即释放数据库服务器资源,有助于避免潜在的内存问题。
PreparedStatement
1.
概述
PreparedStatement
继承
Statement
,并与之在两方面有所不同:
PreparedStatement
对象包含已编译的
SQL
语句,语句已经
“
准备好
”
。
包含于
PreparedStatement
对象中的
SQL
语句可具有一个或多个
IN
参数。
IN
参数的值在
SQL
语句创建时未被指定。相反,该语句为每个
IN
参数保留一个问号(
“
?
”
)作为占位符。每个问号所对应的值必须在该语句执行之前,通过适当的
setXXX
方法来提供。
由于
PreparedStatement
对象已预编译过,所以其执行速度要快于
Statement
对象。因此,需要多次重复执行的
SQL
语句经常创建为
PreparedStatement
对象,以提高效率。
作为
Statement
的子类,
PreparedStatement
继承了
Statement
的所有功能。另外它还添加了一整套方法,用于设置发送给数据库以取代
IN
参数占位符的值。同时,三种方法
execute
、
executeQuery
和
executeUpdate
能执行设置好参数的语句对象。
2.
创建
PreparedStatement
对象
以下的代码段(其中
con
是
Connection
对象)创建一个
PreparedStatement
对象:
PreparedStatement pstmt = con.prepareStatement( UPDATE
厂商登记
SET
厂商名
= ? WHERE
厂商编号
= ?);
对象
pstmt
包含语句
UPDATE
厂商登记
SET
厂商名
= ? WHERE
厂商编号
= ?
,该语句带两个
IN
参数占位符,它已发送给数据库,并由服务器为其执行作好了准备。
3.
传递
IN
参数
在执行
PreparedStatement
对象之前,必须设置每个
?
参数的值。这可通过调用
setXXX
方法来完成,其中
XXX
是与该参数相应的类型。例如,如果参数具有
Java
类型
String
,则使用的方法就是
setString
。对于不同类型的参数,一般都会有一个推荐的设置方法和多个可行的设置方法。
setXXX
方法的第一个参数是要设置的参数的序号(从
1
算起),第二个参数是设置给该参数的值。譬如,以下代码将第一个参数设为
“
中华电视机厂
”
,第二个参数设为
“B0A01”
:
pstmt.setString(1,
中华电视机厂
);
pstmt.setString(2, B0A01);
每当设置了给定语句的参数值,就可执行该语句。设置一组新的参数值之前,应先调用
clearParameters
方法清除原先设置的参数值。
4.
使用
setObject
方法
:
可显式地将输入参数转换为特定的
JDBC
类型。
该方法可以接受三个参数,其中第三个参数用来指定目标
JDBC
类型。将
Java Object
发送给数据库之前,驱动程序将把它转换为指定的
JDBC
类型。
如果没有指定
JDBC
类型,驱动程序就会将
Java Object
映射到其缺省的
JDBC
类型,然后将它发送到数据库。这与常规的
setXXX
方法类似。在这两种情况下,驱动程序在将值发送到数据库之前,会将该值的
Java
类型映射为适当的
JDBC
类型。
二者的差别在于
setXXX
方法使用从
Java
类型到
JDBC
类型的标准映射,而
setObject
方法使用从
Java Object
类型到
JDBC
类型的映射。
方法
setObject
允许接受所有
Java
对象,这使应用程序更为通用,并可在运行时接受参数的输入。这样,如果用户在编辑应用程序时不能确定输入类型,可以通过使用
setObject
,对应用程序赋予可接受的
Java
对象,然后由
JDBC
驱动程序自动将其转换成数据库所需的
JDBC
类型。但如果用户已经清楚输入类型,使用相应的
setXXX
方法是值得推荐的,可以提高效率。
5.
将
JDBC NULL
作为
IN
参数发送
setNull
方法允许程序员将
JDBC NULL
值作为
IN
参数发送给数据库。在这种情况下,可以把参数的目标
JDBC
类型指定为任意值,同时参数的目标精度也不再起作用。
6.
发送大的
IN
参数
setBytes
和
setString
方法能够发送无限量的数据。但是,内存要足够容纳相关数据。有时程序员更喜欢用较小的块传递大型的数据,这可通过将
IN
参数设置为
Java
输入流来完成。当语句执行时,
JDBC
驱动程序将重复调用该输入流,读取其内容并将它们当作实际参数数据传输。
JDBC
提供了四种将
IN
参数设置为输入流的方法:
setBinaryStream
用于字节流,
setAsciiStream
用于
ASCII
字符流,
setUnicodeStream
用于
Unicode
字符流,从
JDK1.2
起,输入字符流的新方法为
setCharacterStream
,而
setAsciiStream
和
setUnicodeStream
已经很少用。
7.
获得参数元数据
JDBC 3.0
实现了
getParameterMetaData()
方法,通过这个方法可以获得有关
IN
参数的各种属性信息,比如类型、精度、刻度等信息,类似于结果集元数据的内容。通过这些信息,用户可以更准确地设置
IN
参数的值。
`
在下面的代码中涉及到了这种方法:
PreparedStatement pstmt = conn.prepareStatement(SELECT * FROM BOOKLIST “ + “WHERE ISBN = ? );
...
//
获得参数元数据对象
ParameterMetaData pmd = pstmt.getParameterMetaData();
//
获得参数的个数
int paramCount = pstmt.getParameterCount();
//
获得第一参数的类型
int colType = pmd.getParameterType(1);
…
8.
自定义方法列表
为了实现对达梦数据库所提供的时间间隔类型和带纳秒的时间类型的支持,在实现
PreparedStatement
接口的过程中,增加了一些自定义的扩展方法。用户将获得的
PreparedStatement
对象反溯成
DmdbPreparedStatment
类型就可以访问这些方法。
CallableStatement
1.
概述
CallableStatement
用来运行
SQL
存储过程。存储过程是数据库中已经存在的
SQL
语句,它通过名字调用。
CallableStatement
是
PreparedStatement
的子类。
CallableStatement
中定义的方法用于处理
OUT
参数或
INOUT
参数的输出部分:注册
OUT
参数的
JDBC
类型(一般
SQL
类型)、从这些参数中检索结果,或者检查所返回的值是否为
JDBC NULL
。
2.
创建
CallableStatement
对象
CallableStatement
对象是用
Connection.prepareCall
创建的。
以下代码创建
CallableStatement
对象,其中含有对存储过程
p1
的调用,
con
为连接对象:
CallableStatement cstmt = con.prepareCall(call p1(?, ?));
其中
?
占位符为
IN
、
OUT
还是
INOUT
参数,取决于存储过程
p1
。
3. IN
和
OUT
参数
将
IN
参数传给
CallableStatement
对象是通过
setXXX
方法完成的。该方法继承自
PreparedStatement
。所传入参数的类型决定了所用的
setXXX
方法(例如,用
setString
来传入
String
值等)。
如果存储过程返回
OUT
参数,则在执行
CallableStatement
对象之前必须先注册每个
OUT
参数的
JDBC
类型,有的参数还要同时提供刻度。注册
JDBC
类型是用
registerOutParameter
方法来完成的。语句执行完后,
CallableStatement
的
getXXX
方法将取回参数值。其中
XXX
是为各参数所注册的
JDBC
类型所对应的
Java
类型。换言之,
registerOutParameter
使用的是
JDBC
类型(因此它与数据库返回的
JDBC
类型匹配),而
getXXX
将之转换为
Java
类型。
设存储过程
p1
的定义如下:
CREATE OR REPLACE PROCEDURE p1( a1 IN CHAR(5), a2 OUT CHAR(20)) AS
DECLARE CUR1 CURSOR FOR
SELECT
厂商名
FROM
厂商登记
WHERE
厂商编号
= a1;
BEGIN
OPEN CUR1;
FETCH CUR1 INTO a2;
END;
以下代码先注册
OUT
参数,执行由
cstmt
所调用的存储过程,然后检索通过
OUT
参数返回的值。方法
getString
从
OUT
参数中取出字符串:
CallableStatement cstmt = con.prepareCall(call p1(?, ?));
cstmt.setString(1, B0A05);
cstmt.registerOutParameter(2, java.sql.Types.VARCHAR);
cstmt.executeUpdate();
String x = cstmt.getString(2);
4. INOUT
参数
如果参数为既接受输入又接受输出的参数类型(
INOUT
参数),那么除了调用
registerOutParameter
方法外,还要调用对应的
setXXX
方法(继承自
PreparedStatement
)。
setXXX
方法将参数值设置为输入参数,而
registerOutParameter
方法将它的
JDBC
类型注册为输出参数。
setXXX
方法提供一个
Java
值,驱动程序先把这个值转换为
JDBC
值,然后将它送到数据库服务器。
该
IN
值的
JDBC
类型和提供给
registerOutParameter
方法的
JDBC
类型应该相同。如果要检索输出值,就要用对应的
getXXX
方法。
设有一个存储过程
p2
的定义如下:
CREATE OR REPLACE PROCEDURE p2(a1 INOUT CHAR(20)) AS
DECLARE CUR1 CURSOR FOR
SELECT
厂商名
FROM
厂商登记
WHERE
厂商编号
= a1;
BEGIN
OPEN CUR1;
FETCH CUR1 INTO a1;
END;
以下代码中,方法
setString
把参数设为
“B0A05”
。然后,
registerOutParameter
将该参数注册为
JDBC VARCHAR
。执行完该存储过程后,将返回一个新的
JDBC VARCHAR
值。方法
getString
将把这个新值作为
Java
的
String
类型返回。
CallableStatement cstmt = con.prepareCall(call p2(?));
cstmt.setString(1, B0A05);
cstmt.registerOutParameter(1, java.sql.Types.VARCHAR);
cstmt.executeUpdate();
String x = cstmt.getString(1);
5.
利用参数名进行操作
在通常的情况下一般采用参数索引来进行赋值。
JDBC3.0
规范要求可以利用参数名来对参数进行赋值,
DM4 JDBC 3.0
驱动程序实现了这一点。如果某个存储过程的一些参数有默认值,这时候采用参数名进行赋值就非常有用,用户可以只对那些没有默认值的参数进行赋值。参数名可以通过调用
DatabaseMetaData.getProcedureColumns()
来获得。
下面的代码中,存储过程
p2
为上面那个存储过程
p2
。利用参数名进行操作:
CallableStatement cstmt = con.prepareCall({CALL p2 (?)});
cstmt.setString(a1, B0A05);
cstmt.registerOutParameter(a1, java.sql.Types.VARCHAR);
cstmt.executeUpdate();
String x = cstmt.getString(a1);
而且,在读取参数的值和进行参数注册的时候,
setXXX
、
getXXX
、
registerOutParameter
也都可以采用参数名来进行操作。通过调用
DatabaseMetaData.supportsNamedParameters()
方法就可以确定
JDBC
驱动程序是否支持利用参数名来进行操作。
注意:在执行同一条语句的过程中,不允许交叉使用参数索引和参数名来进行操作,否则会抛出异常。
6.
自定义方法列表
为了实现对达梦数据库所提供的时间间隔类型和带纳秒的时间类型的支持,在实现
CallableStatement
接口的过程中,增加了一些自定义的扩展方法。用户将获得的
CallableStatement
对象反溯成
DmdbCallableStatment
类型就可以访问这些方法。这些方法所涉及到的扩展类请参看
1.2.16
扩展类这一节。
表
1.2.3
:
自定义方法列表
方法名
功能说明
getINTERVALYM(int)
获取指定列的
DmdbIntervalYM
类型值。
getINTERVALYM(String)
获取指定列的
DmdbIntervalYM
类型值。
getINTERVALDT(int)
获取指定列的
DmdbIntervalDT
类型值。
getINTERVALDT(String)
获取指定列的
DmdbIntervalDT
类型值。
getTIME(int)
获取指定列的
DmdbTime
类型值。
getTIME(String)
获取指定列的
DmdbTime
类型值。
setTIME(String, DmdbTime)
根据参数名来设置
DmdbTime
类型值。
setINTERVALDT(String, DmdbIntervalDT)
根据参数名来设置
DmdbIntervalDT
类型值。
setINTERVALYM(String, DmdbIntervalYM)
根据参数名来设置
DmdbIntervalYM
类型值。
ResultSet
1.
概述
ResultSet
提供执行
SQL
语句后从数据库返回结果中获取数据的方法。执行
SQL
语句后数据库返回结果被
JDBC
处理成结果集对象,可以用
ResultSet
对象的
next
方法以行为单位进行浏览,用
getXXX
方法取出当前行的某一列的值。
通过
Statement
,
PreparedStatement
,
CallableStatement
三种不同类型的语句进行查询都可以返回
ResultSet
类型的对象。
2.
行和光标
ResultSet
维护指向其当前数据行的逻辑光标。每调用一次
next
方法,光标向下移动一行。最初它位于第一行之前,因此第一次调用
next
将把光标置于第一行上,使它成为当前行。随着每次调用
next
导致光标向下移动一行,按照从上至下的次序获取
ResultSet
行。
在
ResultSet
对象或对应的
Statement
对象关闭之前,光标一直保持有效。
3.
列
方法
getXXX
提供了获取当前行中某列值的途径。在每一行内,可按任何次序获取列值。
列名或列号可用于标识要从中获取数据的列。例如,如果
ResultSet
对象
rs
的第二列名为
“title”
,则下列两种方法都可以获取存储在该列中的值:
String s = rs.getString(title);
String s = rs.getString(2);
注意列是从左至右编号的,并且从
1
开始。
关于
ResultSet
中列的信息,可通过调用方法
ResultSet.getMetaData
得到。返回的
ResultSetMetaData
对象将给出其
ResultSet
对象各列的名称、类型和其他属性。
4.
采用流方式获取列值
为了获取大数据量的列,
JDBC
驱动程序提供了四个获取流的方法:
getBinaryStream
返回只提供数据库原字节而不进行任何转换的流。
getAsciiStream
返回提供单字节
ASCII
字符的流。
getUnicodeStream
返回提供双字节
Unicode
字符的流。
getCharacterStream
返回提供双字节
Unicode
字符的
java.io.Reader
流。
在这四个函数中,
JDBC
规范不推荐使用
getCharacterStream
方法,其功能可以用
getUnicodeStream
代替。
5. NULL
结果值
要确定给定结果值是否是
JDBC NULL
,必须先读取该列,然后使用
ResultSet
对象的
wasNull
方法检查该次读取是否返回
JDBC NULL
。
当使用
ResultSet
对象的
getXXX
方法读取
JDBC NULL
时,将返回下列值之一:
Java null
值:对于返回
Java
对象的
getXXX
方法(如
getString
、
getBigDecimal
、
getBytes
、
getDate
、
getTime
、
getTimestamp
、
getAsciiStream
、
getUnicodeStream
、
getBinaryStream
、
getObject
等)。
零值:对于
getByte
、
getShort
、
getInt
、
getLong
、
getFloat
和
getDouble
。
false
值:对于
getBoolean
。
6.
结果集增强特性
在
JDBC
驱动程序中提供了符合
JDBC 2.0
标准的结果集增强特性:可滚动、可更新结果集。及
JDBC3.0
标准的可持有性。
(1)
结果集的可滚动性
通过执行语句而创建的结果集不仅支持向前(从第一行到最后一行)浏览内容,而且还支持向后(从最后一行到第一行)浏览内容的能力。支持这种能力的结果集被称为可滚动的结果集。可滚动的结果集同时也支持相对定位和绝对定位。绝对定位指的是通过指定在结果集中的绝对位置而直接移动到某行的能力,而相对定位则指的是通过指定相对于当前行的位置来移动到某行的能力。
JDBC
驱动程序中支持只向前滚结果集
(ResultSet.TYPE_FORWARD_ONLY)
和滚动不敏感结果集
(ResultSet.TYPE_SCROLL_INSENSITIVE)
两种结果集类型,不支持滚动敏感结果集
(ResultSet.TYPE_SCROLL_SENSITIVE)
。当结果集为滚动不敏感结果集时,它提供所含基本数据的静态视图,即结果集中各行的成员顺序、列值通常都是固定的。
(2)
结果集的可更新性
DM4 JDBC
驱动程序中提供了两种结果集并发类型:只读结果集
(ResultSet.CONCUR_READ_ONLY)
和可更新结果集
(ResultSet.CONCUR_UPDATABLE)
。采用只读并发类型的结果集不允许对其内容进行更新。可更新的结果集支持结果集的更新操作。
(3)
结果集的可持有性
JDBC 3.0
提供了两种结果集可持有类型:提交关闭结果集
(ResultSet.CLOSE_CURSORS_AT_COMMIT)
和跨结果集提交
(ResultSet.HOLD_CURSORS_OVER_COMMIT)
。采用提交关闭结果集类型的结果集在事务提交之后被关闭,而跨结果集提交类型的结果集在事务提交之后仍能保持打开状态。
通过
DatabaseMetaData.supportsHoldability()
方法可以确定驱动程序是否支持结果集的可持有性。目前
DM4
支持这两种类型。
(4)
性能优化
JDBC
驱动程序的结果集对象中提供了方法
setFetchDirection
和
setFetchSize
来设置缺省检索结果集的方向和缺省一次从数据库获取的记录条数。它们的含义与用法和语句对象中的同名函数是相同的。
7.
更新大对象数据
从
JDBC 2.0
驱动程序就支持可更新的结果集,但是对
LOB
对象只能读取,而不能更新,这也是
JDBC 2.0
标准所规定的。而
JDBC 3.0
规范规定用户可以对
LOB
对象进行更新,
DM4 JDBC 3.0
驱动程序中实现了这一点:
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(select comment from booklist +
where isbn = 140185852);
rs.next();
Clob commentClob = new Clob(...)
;
rs.updateClob(author, commentClob); // commentClob is a Clob Object
rs.updateRow();
ResultSetMetaData
1.
概述
ResultSetMetaData
提供许多方法,用于读取
ResultSet
对象返回数据的元信息。包括:列名、列数据类型、列所属的表、以及列是否允许为
NULL
值等,通过这些方法可以确定结果集中列的一些信息。
2.
创建结果集元数据对象
结果集元数据是用来描述结果集的特征,所以,需要首先执行查询获得结果集,才能创建结果集元数据对象。
3.
创建
ResultSetMetaData
对象如下例所示:
假如有一个表
TESTTABLE(no int,name varchar(10))
,利用下面的代码就可以知道这个表的各个列的类型:
ResultSet rs = stmt.executeQuery(SELECT * FROM TESTTABLE);
ResultSetMetaData rsmd = rs.getMetaData();
for(int i = 1; i <= rsmd.getColumnCount(); i ++)
{
String typeName = rsmd.getColumnTypeName(i);
System.out.println(
第
+ i +
列的类型为:
+ typeName);
}
DatabaseMetaData
1.
概述
DatabaseMetaData
提供了许多方法,用于获取数据库的元数据信息。包括:描述数据库特征的信息
(
如是否支持多个结果集
)
、目录信息、模式信息、表信息、表权限信息、表列信息、存储过程信息等。
DatabaseMetaData
有部分方法以
ResultSet
对象的形式返回结果,可以用
ResultSet
对象的
getXXX()
方法获取所需的数据。
2.
创建数据库元数据对象
数据库元数据对象由连接对象创建。以下代码创建
DatabaseMetaData
对象(其中
con
为连接对象):
DatabaseMetaData dbmd = con.getMetaData();
利用该数据库元数据对象就可以获得一些有关数据库和
JDBC
驱动程序的信息:
String databaseName = dbmd.getDatabaseProductName(); //
数据库产品的名称
int majorVersion = dbmd.getJDBCMajorVersion(); // JDBC
驱动程序的主版本号
String []types ={TABLE};
ResultSet tablesInfor = dbmd.getTables(null, null, “*TE%”, types);
数据类型访问
1
.概述
对数据的访问主要是
(1)
通过
PreparedStatement
对象、
CallableStatement
对象的
setXXX
方法以及
ResultSet
对象的
updateXXX()
方法进行设置
;
(2)
通过
CallableStatement
对象、
ResultSet
对象的
getXXX()
方法来进行检索。
2
.各个类型能采用的
setXXX
方法或
updateXXX
方法
请参看
SUN
公司的
JDBC 3.0 specification
文档第
186
页的
TABLE-6
。一般地,只要把里面的
getXXX
改为
setXXX
或
updateXXX
即可。
3
.各个类型能采用的
getXXX
方法
请参看
SUN
公司的
JDBC 3.0 specification
文档第
186
页的
TABLE-6
。
ParameterMetaData
1
.概述
参数元数据是
JDBC 3.0
标准新引入的接口,它主要是对
PreparedStatement
、
CallableStatement
对象中的
?
参数进行描述,例如参数的个数、参数的类型、参数的精度等信息,类似于
ResultSetMetaData
接口。通过引入这个接口,就可以对参数进行较为详细、准确的操作。
2
.创建参数元数据对象
通过调用
PreparedStatement
或
CallableStatement
对象的
getParameterMetaData()
方法就可以获得该预编译对象的
ParameterMetaData
对象:
ParameterMetaData pmd = pstmt.getParameterMetaData();
然后就可以利用这个对象来获得一些有关参数描述的信息:
//
获取参数个数
int paraCount = pmd.getParameterCount();
for(int i = 1; i <= paraCount; i ++) {
//
获取参数类型
System.out.println(The Type of Parameter(+i+) is + ptmt.getParameterType(i));
//
获取参数类型名
System.out.println(The Type Name of Parameter(+i+) is
+ ptmt.getParameterTypeName(i));
//
获取参数精度
System.out.println(The Precision of Parameter(+i+) is + ptmt.getPrecision(i));
//
获取参数是否为空
System.out.println(Parameter(+i+) is nullable? + ptmt.isNullable (i));
}
大对象
1
.概述
JDBC
标准为了增强对大数据对象的操作,在
JDBC 3.0
标准中增加了
java.sql.Blob
和
java.sql.Clob
这两个接口。这两个接口定义了许多操作大对象的方法,通过这些方法就可以对大对象的内容进行操作。
2
.产生
Lob
对象
在
ResultSet
和
CallableStatement
对象中调用
getBlob()
和
getClob()
方法就可以获得
Blob
对象和
Clob
对象:
Blob blob = rs.getBlob(1);
Clob clob = rs.getClob(2);
3
.设置
Lob
对象
Lob
对象可以像普通数据类型一样作为参数来进行参数赋值,在操作
PreparedStatement
、
CallableStatement
、
ResultSet
对象时使用:
PreparedStatement pstmt = conn.prepareStatement(INSERT INTO bio (image, text) “ +
“VALUES (?, ?));
//authorImage is a Blob Object
pstmt.setBlob(1, authorImage);
//authorBio is a Clob Object
pstmt.setClob(2, authorBio);
在一个可更新的结果集中,也可以利用
updateBlob(int,Blob)
和
updateClob(int,Clob)
来更新当前行。
4
.改变
Lob
对象的内容
Lob
接口提供了方法让用户可以对
Lob
对象的内容进行任意修改:
byte[] val = {0,1,2,3,4};
Blob data = rs.getBlob(DATA);
int numWritten = data.setBytes(1, val); //
在指定的位置插入数据
PreparedStatement ps = conn.prepareStatement(UPDATE datatab SET data = ?);
ps.setBlob(DATA, data);
ps.executeUpdate();
Savepoint
1
.概述
为了增加对事务的控制,
JDBC
规范
3.0
增加了
Savepoint
这个接口。它代表一个逻辑事务点。在非自动提交模式下,一个事务中可以设置多个
Savepoint
。这样在回滚时,可以回滚到指定的
Savepoint
,从事务开始到该
Savepoint
之间的操作依然保留着。这就提高了事务处理的粒度,更好地操纵数据。
Savepoint
分为命名的和未命名的两种。未命名的用系统分配的
ID
作为标识。同时可以通过
DatabaseMetaData.supportsSavepoint()
来判断
JDBC
驱动程序是否支持
Savepoint
。
2
.操作
Savepoint
Savepoint
的操作位于
Conncetion
接口:
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(insert into tab1(col) values(' first') ); //
插入第一条数据
Savepoint svpt1 = conn.setSavepoint(SAVEPOINT_1); //
设置一个
Savepoint
rows = stmt.executeUpdate(intert into tab1(col) values('second') ); //
插入第二条数据
……
conn.rollback(svpt1); //
回滚到指定的
Savepoint
……
conn.commit(); //
提交事务
,
真正在数据库中仅插入了第一条数据
这样,数据库中仅增加了第一次插入的那条记录。注意:在使用
Savepoint
之前,一定要把当前连接设置为非自动提交模式。
在事务提交之后,先前事务中的所有
Savepoint
都自动取消。如果有两个
Savepoint
,当事务回滚到前面的那个
Savepoint
时,后面的这个
Savepoint
也自动取消。
autoGenerated Key
在很多数据库中,插入一条新的记录时数据库会为新增的记录自动产生一个唯一的标识。
JDBC3.0
规范中的
Statement
新增了一个方法:
getGeneratedKeys
,利用这个方法就可以检索出系统自动为插入的新行所产生的关键字。可以传递一个
Statement.RETURN_GENERATED_KEYS
标识给
Statement
对象的
execute
、
executeUpdate()
的方法或者
PreparedStatement
对象的一些方法,这样在执行完这些方法之后就可以检索新产生的关键字。
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(insert into orders(isbn,customerid) values(1953, 'billg') ,
Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
boolean b = rs.next();
if (b)
{
//
检索新产生的关键字的值
……
}
为了检索方便,用户也可以为自动产生的关键字指定列名或者索引:
String[] keyColumn = {order_id};
… …
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(insert into orders (isbn,customerid) values(9664, 'Billg') ,keyColumn);
ResultSet rs = stmt.getGeneratedKeys();
while(rs.next())
{
//
检索新产生的关键字的值
byte[] bs = rs.getBytes(order_id);
}
……
JDBC
驱动程序是否支持自动产生的关键字,可以通过
DataBaseMetaData.supportsGetGeneratedKeys
来判断。
数据源
DataSource
数据源是
JDBC 2.0
规范作为扩展包引入的,在
JDBC 3.0
规范中成为核心
API
。数据源不仅能够从功能上完全取代利用
DriverManager
建立连接的方式,而且具有以下几点优势:
(1)
增强了代码的可移植性;
(2)
方便了代码的维护;
(3)
利用连接池来提高系统的性能。
JDBC
驱动程序提供了对数据源的支持,实现了
javax.sql.DataSource
接口和
java.sql.ConnectionPoolDataSource
接口。用户通过
javax.sql.DataSource
接口来建立连接。
使用数据源来建立连接时,
首先要向
JNDI
注册一个数据源。在建立连接的时候,首先通过
JNDI
来获得要使用的数据源:
DataSource ds = (DataSource) ctx.lookup(datasourceName)
;
然后使用这个数据源来建立连接对象:
Connection con = ds.getConnection()
;
该连接同通过
DriverManager
所建立的连接是一样的。
实现
javax.sql.ConnectionPoolDataSource
接口是为了提高系统的性能。通过设置一个连接缓冲区,在其中保持数目较小的物理连接的方式,这个连接缓冲区由大量的并行用户共享和重新使用,从而避免在每次需要时建立一个新的物理连接,以及当其被释放时关闭该连接的昂贵操作。该连接池是
JDBC
提供系统性能的一种措施,是在
JDBC
内部实现的,能够为用户提供透明的高速缓冲连接访问。用户利用数据源来建立连接的应用不需为此做出任何代码上的变动。
posted on 2006-07-25 08:49
Lizzie 阅读(2606)
评论(0) 编辑 收藏 所属分类:
专业积木