类似地,如果获取了Clob对象,那么就可以通过调用getSubString或getCharacterStream方法来获取其中的字符数据。
要将LOB置于数据库中,需要在Connection对象上调用createBlob或createClob,然后获取一个用于该LOB的输出流或写出器,写出数据,并将该对象存储到数据库中。例如,下面展示了如何存储一张图像:
Blob coverBlob = connection.createBlob();
int offset = 0 ;
OutputStream out = coverBlob.setBinaryStream(offset);
ImageIO.write(coverImage, "PNG" , out);
PreparedStatement stat = conn.prepareStatement("INSERT INTO Cover VALUES(?, ?)" );
stat.set( 1 , isbn);
stat.set( 2 ,coverBlob);
stat.executeUpdate();
2. 可滚动和可更新的结果集
要让ResultSet可以滚动个和更新,必须在创建Statement对象的时候使用下面的方式指定对应的参数:
Statement stmt = conn.createStatement(type, concurrency);
对于PreparedStatement,使用下面的方式指定参数:
PreparedStatement pstmt = conn.prepareStatement(sql, type, concurrency);
其中,type表示ResuleSet的类型,而concurrency表示是否可以使用ResuleSet来更新数据库。
type和concurrency的取值以及含义如下:
ResultSet类的type值 值 解释 ResultSet.TYPE_FORWARD_ONLY 结果集不能滚动(默认值) ResultSet.TYPE_SCROLL_INSENSITIVE 结果集可以滚动,但ResuleSet对数据库中数据变化不敏感 ResultSet.TYPE_SCROLL_SENSIT IVE 结果集可以滚动,并且ResuleSet对数据库中发生的改变敏感 ResultSet类的Concurrency值 值 解释 ResultSet.CONCUR_READ_ONLY 结果集不能用于更新数据库(默认值) ResultSet.CONCUR_UPDATABLE 结果集可以用于更新数据库JDBC的结果集有很多类型。这些结果集有不同的特性,以满足各种需要。这在高性能的JDBC数据操作中有着重要应用。下面是一个应用实例:
package lavasoft测试数据mon;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* JDBC可滚动可更新感知更新结果集测试
*
* @author leizhimin 2009-12-8 20:09:03
*/
public class TestResultSet {
public static void main(String[] args) {
testScrollResultSet();
testUpdateResultSet();
}
/**
* 可更新结果集更新测试
*/
public static void testUpdateResultSet() {
Connection conn = DBToolkit.getConnection();
String sql = "SELECT * FROM book" ;
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sql);
System.out.println( "---------原结果集--------" );
while (rs.next()) {
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
}
System.out.println( "---------插入一条记录--------" );
rs.first();
// 将光标移动到插入行上
rs.moveToInsertRow();
// 构建行数据
rs.updateString(2, "xxxx" );
rs.updateString( 3, "x" );
// 插入一行
rs.insertRow();
System.out.println( "-------------更新一条记录-------------" );
rs.absolute( 3 );
// 构建行数据
rs.updateString(2, "uuuu" );
rs.updateString( 3, "u" );
rs.updateRow();
System.out.println( "---------插入更新后的结果集--------" );
rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
}
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBToolkit.closeConnection(conn);
}
}
/**
* 可滚动结果集滚动测试
*/
public static void testScrollResultSet() {
Connection conn = DBToolkit.getConnection();
String sql = "SELECT * FROM book" ;
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
}
System.out.println( "------前滚操作-----" );
// 将光标移动到此 ResultSet 对象的上一行
rs.previous();
rs.previous();
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
System.out.println( "------绝对定位-----" );
// 将光标移动到此 ResultSet 对象的给定行编号。
rs.absolute(3 );
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
System.out.println( "------移动到第一行-----" );
// 将光标移动到此 ResultSet 对象的第一行。
if (rs.first()) {
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
}
System.out.println( "------移动到最后一行-----" );
// 将光标移动到此 ResultSet 对象的第一行。
if (rs.last()) {
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
}
System.out.println( "------移动到第一行之前-----" );
// 将光标移动到此 ResultSet 对象的开头,正好位于第一行之前
rs.beforeFirst();
rs.next();
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
System.out.println( "------移动到最后一行之后-----" );
// 将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
rs.afterLast();
rs.previous();
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
System.out.println( "------相对当前行做移动-----" );
rs.relative( -2 );
System.out.println( "[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3 ));
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBToolkit.closeConnection(conn);
}
}
}
控制台输出:
[行号:1] 1 aaa a [行号: 2] 2 bbb b [行号: 3] 3 ccc c [行号: 4] 4 ddd d [行号: 5] 5 eee e [行号: 6] 6 fff f [行号: 7] 7 ggg g [行号: 8] 8 hhh h ------前滚操作----- [行号: 7] 7 ggg g ------绝对定位----- [行号: 3] 3 ccc c ------移动到第一行----- [行号: 1] 1 aaa a ------移动到最后一行----- [行号: 8] 8 hhh h ------移动到第一行之前----- [行号: 1] 1 aaa a ------移动到最后一行之后----- [行号: 8] 8 hhh h ------相对当前行做移动----- [行号: 6] 6 fff f ---------原结果集-------- [行号: 1] 1 aaa a [行号: 2] 2 bbb b [行号: 3] 3 ccc c [行号: 4] 4 ddd d [行号: 5] 5 eee e [行号: 6] 6 fff f [行号: 7] 7 ggg g [行号: 8] 8 hhh h ---------插入一条记录-------- -------------更新一条记录------------- ---------插入更新后的结果集-------- [行号: 1] 1 aaa a [行号: 2] 2 bbb b [行号: 3] 3 uuuu u [行号: 4] 4 ddd d [行号: 5] 5 eee e [行号: 6] 6 fff f [行号: 7] 7 ggg g [行号: 8] 8 hhh h [行号: 9] 9 xxxx x Process finished with exit code 0
可保存性:设置提交时候是否关闭结果集。
ResultSet.HOLD_CURSORS_OVER_COMMIT :在提交后结果集还可用
ResultSet.CLOSE_CURSORS_AT_COMMIT:在提交时候关闭结果集
由于这些特性比较高级,不同数据库驱动对此实现也不一样。因此在使用JDBC高级特性的时候最好做个测试,以保证程序的可靠性。
当type设置为:ResultSet.TYPE_SCROLL_INSENSITIVE 或者 ResultSet.TYPE_SCROLL_INSENSITIVE 时,游标可以移动,但是移动的位置是[1,count],记住并不是从0开始,否则会报错。
既然可以移动,那么把移动的几个方法解释一下:
rs = statement.executeQuery(); 游标指向第一行前面的位置,这个位置是不能获取数据,否则报错:结果集没有当前行
rs.next(); // 游标下移一个位置,如果所在位置有结果集那么返回true,否则返回false
rs.previous(); // 游标上移一个位置,如果所在位置有结果集那么返回true,否则返回false
rs.first(); // 游标指向第一行的位置
rs.last(); // 游标指向最后一行的位置
rs.beforeFirst(); // 游标指向第一行前面的位置 , 这个位置不能获取数据
rs.afterLast(); // 游标指向最后一行后面的位置,这个位置不能获取数据
rs.absolute(index); // 游标移动至index位置,index是[1,count]的任意数字,但是不能超出,否则报错
rs.relative(index); // 游标从当前位置算移动index个位置,也就是相对移动,index可以是负数,但是计算结果同样在[1,count]内
isAfterLast(); // 判断游标是否在最后一行之后。
isBeforeFirst();// 判断游标是否在第一行之前。
ifFirst() ; //判断游标是否指向结果集的第一行。
isLast(); // 判断游标是否指向结果集的最后一行。
getRow();// 得到当前游标所指向行的行号,行号从1开始,如果结果集没有行,返回0。
java数据库编程——读写LOB、可滚动和可更新的结果集
标签:
查看更多关于java数据库编程——读写LOB、可滚动和可更新的结果集的详细内容...