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日培训日记(下)”中续写............