9月22日培训日记(上)

首先检查昨天的作业,了解学员对昨天讲解知识的掌握情况。
(1)根据马献忠完成的BasicDataSourceFactory.createDataSource(Properties properties) 方法中设置的properties对象,询问他是怎么知道该如何设置properties对象的,我给大家分析了properties对象中的关键字就是根据BasicDataSource的bean属性来的原因。
(2)检查魏奕东完成的作业情况,下面是他的程序代码
package cn.itcast;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import com.ibatis.common.jdbc.SimpleDataSource;

public class SimpleDataSourceDemo {

public static void main(String[] args) {

Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

Properties props = new Properties();
InputStream ips = InputStream.class.getResourceAsStream("/" + "config.properties");
try {
props.load(ips);
} catch (Exception e) {
e.printStackTrace();
return;
}finally{
try{
ips.close();
ips = null;
}catch(Exception e){
e.printStackTrace();
}
}

try {

SimpleDataSource simpleDS = new SimpleDataSource(props);
conn = simpleDS.getConnection();
pstmt = conn.prepareStatement("select * from pet where species='dog'");
rs = pstmt.executeQuery();

if(!rs.next()){
System.out.println("No record!");
}
else{
rs.beforeFirst();//非滚动结果集而不抛异常,不知其故。
while (rs.next()) {
System.out.println("NAME:" + rs.getString("name") +
"\tOWNER:"+ rs.getString("owner") +
"\tBIRTH:" + rs.getString("birth"));
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(rs != null){
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

}

总体上来说,魏奕东做得不错,接着魏奕东针对他上面的程序向我提了一个问题,与问题相关的代码如下:
if(!rs.next()){
System.out.println("No record!");
}
else{
rs.beforeFirst();//非滚动结果集而不抛异常,不知其故。
while (rs.next()) {
System.out.println("NAME:" + rs.getString("name") +
"\tOWNER:"+ rs.getString("owner") +
"\tBIRTH:" + rs.getString("birth"));
}
}

他从JDK文档中看到:对于非滚动结果集调用beforeFirst方法,应该抛出异常,可是他使用的就是默认的不可滚动的结果集,怎么对这个结果集调用beforeFirst方法不抛出异常。
我先没有直接回答他的这个问题,而是挑出了他程序中的一个大败笔。他上面的程序是先调用rs.next判断是否有记录,如果有记录,再打印出所有记录。在打印所有记录时,他也意识到了游标已移动到第一行,所以,再使用rs.beforeFirst()方法将游标移回到第一行之前,再按照通常的方式对整个结果集进行遍历处理。我笑话他说:“他在走路时,先迈出一步试了试路是否可走,如果可以走,他又退回到起点,然后再向前走;他为何不迈出一步后,发现路可走时,接着迈出的第一步继续往前走呢?”,同学们都哈哈大笑,点头称是,但代码怎么写?我针对魏奕东的代码,给出了如下建议:
do
{
...
}while(rs.next());

再回过头来说为什么不可滚动的结果集调用beforeFirst时,没有抛出异常。我分析两种可能的原因:a.可能是某种驱动程序的原因,换个数据库驱动程序试试;b.在很久以前,要产生可滚动结果集,是一种特殊功能,而对现在的驱动程序来说,这是一项基本功能,只要产生结果集,就是可滚动的,这就好比以前的彩电要带遥控功能需要特殊定制,而现在只要是台彩电,就具有遥控功能,遥控成了彩电的基本配置,要想弄台没有遥控功能的彩电,还弄不到了呢!JDBC规范为了向前兼容,要保留这个参数设置和文档说明,但各个驱动厂商会忽略这点现在看来毫无意义的要求和建议。

针对魏奕东的问题,我补充讲解了可滚动,可更改,保持光标的结果集,主要就是分析了Connection.createStatement(int resultSetType,int resultSetConcurrency,int resultSetHoldability)中的各个参数的作用和各个参数的各种设置值的意义。接着,我又要魏奕东将结果集类型强制设置成ResultSet.TYPE_FORWARD_ONLY,然后看实验结果,他报告在这种情况下,结果集还是可以滚动,看来现在真是难以弄出不可滚动的结果集了,这就像我们难以再弄台没有遥控功能的彩电的道理。然后,我讲解了如何使用可更改的结果集来更改、插入和删除底层数据库中的记录。
为了讲清楚resultSetHoldability这个参数,我又为大家补充了JDBC中的事务处理问题,给出了如下示意代码:
try
{
cn.setAutoCommit(false);
stmt.executeUpdate();
stmt.exectueUpdate();
rs = stmt.executeQuerey();
rs.next();
cn.commit();
rs.next(); //用于测试resultSetHoldability这个参数
}
catch(Exception e)
{
cn.roolback();
}

在上午下课时,临时为同学们布置了一道作业题:通过自己的实验来了解JDBC中的事务处理,了解“可滚动,可更改,保持光标的结果集”的应用。
后面的内容还很多,留在“9月22日培训日记(下)”中续写............

你可能感兴趣的:(sql,bean,jdbc,ibatis,笑话)