根据袁龙友老师前两天上课的反馈信息:学员们对表之间建立关联关系的思想还很陌生,毫无概念。首先检讨我以前写的Java书对对象之间的关联关系强调得不够(几乎就是没有任何提及),而对象之间的关系在实际开发中却用得很多。如果对对象之间的关联关系理解不透,那学习hibernate时将会很费劲,我以后的java书中会将对象之间的关系作为一个重点强调。
今天我先上来用自己的土办法强制学员们建立关联关系的思想,告诉学员们一个系统中的对象不是孤零存在的,而于周围的其他对象之间存在着关系,数据库系统中的一个表也经常与其他表之间存在关系。所以,设计一个对象必须要能立即想到它有三个要素:属性、方法、关系;设计一个数据库的表时立即想到两个要素:字段、关系。不管这种说法是否严谨,反正强迫新手按照这种思路记忆后,以后就很容易设计对象关系和表之间的关联关系了。

用eclipse跟踪调试汪大伦的spring中的JavaBean属性名的第二个字母大写时的问题,跟踪了好久,也没找到是哪一句产生的错误,不知道是eclipse调试器太差,还是spring的源程序与class程序之间的不一致,最大可能性还在于我对Eclipse的调试器掌握得不熟练。最后在网上搜索到结论,问题在于我们对JavaBean规范的理解不够深入。如果类中有两个方法,一个是setter,一个是getter,并且setter的单参数的属性和getter的无参数返回值得类型相同,并且setter返回void,就认为发现了一个属性。并且,setter的名字必须以set字符串开始,getter的名字必须以get开始,或者以is开始并且属性类型是boolean。在上面的情况发生时,get和set之后的名字还必须匹配。这个匹配就是属性的名字,然后如果第二个字母是小写的话,会把其首字母变成小写。

提问复习JdbcTemplate类,由于上次讲解的节奏很快,发现很多人没有完全搞明白,今天继续进行详细讲解。
JdbcTemplate内部可以设计成按照一个非常标准流程来执行JDBC的一条sql操作,但是,它无法事先知道用户具体要执行怎样的sql操作,即无法用户是要执行增加、还是删除、还是修改的sql语句,也就是执行到生成PreparedStatement对象时,它就不知道该如何生成了,因此JdbcTemplate将生成PreparedStatement对象的任务委托给用户,说:“请你给我一个PreparedStatement对象,好吗?”所以,用户应向JdbcTemplate提供sql语句,向JdbcTemplate提供sql语句无非也就是为了生成PreparedStatement对象,如果用户向JdbcTemplate提供一个PreparedStatement对象,也就等于向其提供了要执行的sql语句,因为PreparedStatement对象中包含了sql语句。
提问:向JdbcTemplate提供Statement对象能让其知道要执行的sql语句吗?帮助大家加深理解Statement与PreparedStatement的差别之一。

用户可以给JdbcTemplate提供一个sql语句(原材料),也可以直接给它一个preparedstatement对象,还给它一个preparedstatement对象的生产器。JdbcTemplate有了preparedstatement对象后,它再如何执行preparedstatement对象和处理返回结果时又犯难了,又通过一个PreparedStatementCallback对象来委托给用户自己处理。如果仅仅是增加、删除、修改的sql语句,JdbcTemplate可以采用简单的方式进行处理,因此可以不需要呼叫一个PreparedStatementCallback对象来处理,对于这种情况,使用update方法来专门处理。在提供preparedstatement后,还需要提供preparedstatementsetter对象来进一步设置参数。对于查询的处理比较复杂,使用query方法来专门处理,query方法也有多种形式:ResultSetExtractor把整个结果集给你,你自己负责while循环处理。用于不需要循环结果的情况,例如,得到表结构,得到max(id)这样的情况。RowCallbackHandler:我每遇到一行时,都交给你去处理,我不问处理结果。ResultReader扩展了RowCallbackHandler:我每遇到一行时,都交给你去处理,我相信你会把每行的结果放到一个集合中,我等会调用getResults方法来获得那个集合,示例代码如下:
MyResultReader implements ResultReader
{
 List list = new Vector();
 processRow(Result rs)
 {
  list.add(rs.getString(2));
 }
 
 List getResults()
 {
  return list;
 }
}

直接用网页往数据库里插入数据,运行效率更高,为什么不这么做?软件分层设计的好处,可维护性,面向对象带来的好处等等。RowMapper的作用:spring请你帮个忙:“我不知道把这一条记录变成一个怎样的对象,你帮我做吧”

通过使用了一段时间的spring,请用你自己话说说什么是框架:框架让我们将原来必须用程序代码写的东西变成了通过书写XML即可完成。
学员锻炼:以JdbcTemplate为例,上台讲解策略模式。

讲解BatchPreparedStatement,回顾区分statement.addbatch和prestatement.addbatch。

李杰完成的实验结果:网络断线多长时间,rs.next都可以,但时间较长,cn.createStatement就不行了。
原因与实际问题的思考:网络是虚连接,应考虑web server与database server不在同一台服务器上的时候,网络断线或database server重新启动的情况,这也是cn.createStatement有可能失败的原因之一。这个实验最好还是配合Statement.setFetchSize/getFetchSize再试试!

如果类A实现了两个接口X和Y,而另外一个类B的两个同名方法分别以一个接口X或Y作为参数,调用类B的该方法,并以类A的实例对象作为参数,会有什么问题呢?可以自己进行强制转换。

作业:接着spring的rowmapper把数据库表中的记录变成一个对象集合返回,再把集合打印出来。

教学心得:有些关键的、宝贵的思想,老师虽然讲解出来了(可能只是十几秒钟),但是,学员们不一定能够意思到其重要性,过后很容易忘记,老师应把这样的东西作为faq提出来,并要求学员们作为问题自己提问,例如,使用preparedstatement的优点等。