最近写程序已经很少直接用JDBC了,一直都是用ibaits, Hibernate等来招呼,因为现在的集成框架已经很稳定了。不过对JDBC的直接使用还是不可以忽略的,JDBC3.0提供的n多的新特征还是要熟悉了解的,以前学jdbc的时候就是上网找些demo和介绍来学,使用很单一,对JDBC3.0的好多新的特征都忽略了,比如下面一个例子:
Statement stmt = con.createStatement();
ResultSet rs =
stmt.executeQuery("SELECT * FROM user WHERE
username='aa'");
stmt.executeUpdate("UPDATE user SET lastdatetime=now() where
username='aa'");
这是一个用户登录时,经常用到的代码,先是根据用户名aa查找该用户的详细信息,然后再更新该用户的最后登录时间(lastdatetime)。这这个里面,我们用了两个sql语句,这个是我一直用的方法,但是如果用JDBC2.0给我们提供的便利,我们只要写一条sql就够了,其他的都交给jdbc,看下面的代码:
Statement stmt2 =
con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet
rs2 = stmt.executeQuery("SELECT * FROM user WHERE
username='aa'");
rs2.next();
rs2.updateDate("lastdatetime", new
Date(Calendar.getInstance().getTimeInMillis()));
rs2.updateRow();
这里面最主要的特征就是ResultSet.TYPE_FORWARD_ONLY和ResultSet.CONCUR_UPDATABLE,通过初始化Statement时传不同的参数,可以对ResultSet进行不用的错作限制。con.createStatement的时候,有三种可以掉用的函数:
1、createStatement();
2、createStatement(int resultSetType, int
resultSetConcurrency)
3、createStatement(int resultSetType, int
resultSetConcurrency, int resultSetHoldability)
其中resultSetType可选值是:
1、ResultSet.TYPE_FORWARD_ONLY
在ResultSet中只能先前移动游标,
2、ResultSet.TYPE_SCROLL_INSENSITIVE
在ResultSet中可以随心所欲的先前向后移动游标,
3、ResultSet.TYPE_SCROLL_SENSITIVE
在ResultSet中可以随心所欲的先前向后移动游标,同时ResultSet的值有所改变的时候,他可以得到改变后的最新的值
其中resultSetConcurrency可选值是:
1、ResultSet.CONCUR_READ_ONLY 在ResultSet中的数据记录是只读的,可以修改
2、ResultSet.CONCUR_UPDATABLE
在ResultSet中的数据记录可以任意修改,然后更新会数据库
其中resultSetHoldability可选值是:
1、ResultSet.HOLD_CURSORS_OVER_COMMIT 表示修改提交时,不关闭ResultSet的游标
2、ResultSet.CLOSE_CURSORS_AT_COMMIT 表示修改提交时,关闭ResultSet的游标
对于查询操作第一种初始化方法createStatement(),相当于第二种方法的createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY),第三种方法的createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT)
下面写一段demo的代码,我把一些特征函数都用出来,但是只是用来查考和说明名灵活性的。
Statement stmt2 =
con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet
rs2 = stmt.executeQuery("SELECT * FROM
user");
rs2.next();
rs2.updateDate("lastdatetime", new
Date(Calendar.getInstance().getTimeInMillis()));
rs2.updateRow();
rs2.afterLast();
while(rs2.previous()){
/**....*/ }
rs.beforeFirst();
while(rs2.next()){ /**....*/
}
rs.last();
rs.first();
rs.absolute(5); //游标移动到第5条
rs.absolute(-1);
//游标移动到最后一条
rs.relative(-5); //游标向上移动5条
rs.relative(2);
//游标向下移动2条
rs.deleteRow(); //删除当前行
rs.last();
//游标移动到最后
rs.updateString("summary", "This is ...");
//设置更新的字段值
rs.cancelRowUpdates(); //取消刚才输入的更新
rs.getRow();
//得到当前行号
rs.moveToInsertRow(); //游标移动到要新增的那条记录上
rs.updateInt("id",
1);
rs.updateString(2, "my name");
rs.insertRow(); //插入新记录
JDBC2.0提供的还有一个功能就是数据库的批量操作:
con.setAutoCommit(false);
Statement stmt3 =
con.createStatement();
stmt3.addBatch("insert
.....");
stmt3.addBatch("insert .....");
int[] rows =
stmt3.executeBatch();
con.commit();
但是有一点要注意,stmt3.executeBatch()他不会自动给你回滚数据操作,当你有5条update语句的时候,如果第三条发生错误,那么将无法自动回滚前两条update语句的影响,所以一定要自己手工进行事务管理。
在您的事务中使用 Savepoint
JDBC3.0中最令人兴奋的附加特点就是 Savepoint
了。有时候需要的是对事务多一点的控制,而不是在当前的事务中简单地对每一个改变进行回滚。在JDBC3.0下,您就可以通过 Savepoint
获得这种控制。Savepoint 接口允许您将事务分割为各个逻辑断点,以控制有多少事务需要回滚。看下面的代码:
conn.setAutoCommit(false);
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(
"INSERT INTO authors (first_name, last_name) valueS(′Lewis′, ′Carroll′)");
Savepoint svpt = conn.setSavepoint("NewAuthor");
try{
rows =
stmt.executeUpdate( "UPDATE authors set type = ′fiction′ WHERE last_name =
′Carroll′");
}catch(Exception e){
conn.rollback(svpt);
rows =
stmt.executeUpdate( " update .......... other sql ");
}
conn.commit();
上面代码显示,当UPDATE authors失败的时候,系统事务回滚UPDATE authors的sql的影响,而INSERT
INTO authors的sql仍然有效
检索自动产生的关键字
为了解决对获取自动产生的或自动增加的关键字的值的需求,JDBC
3.0现在将获取这种值变得很轻松。要确定任何所产生的关键字的值,只要简单地在语句的 execute()
方法中指定一个可选的标记,Statement.RETURN_GENERATED_KEYS和Statement.NO_GENERATED_KEYS。在执行这条语句后,所产生的关键字的值就会通过从
Statement 的实例方法 getGeneratedKeys() 来检索 ResultSet 而获得。ResultSet
包含了每个所产生的关键字的列。看下面代码:
Statement stmt = conn.createStatement();
stmt.executeUpdate("INSERT INTO authors (first_name, last_name) valueS
(′George′, ′Orwell′)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs =
stmt.getGeneratedKeys();
if ( rs.next() ) {
int key = rs.getInt();
}
参考资料:
http://java.sun.com/j2se/1.5.0/docs/api/java/sql/package-summary.html