在Hibernate(十六): DetachedCriteria子查询与ALIAS_TO_ENTITY 的 末尾,问题的焦点集中到hibernate对生成PreparedStatement的处理上. 接着再追问: 是不是Hibernate对那个preparedStatement做了什么特殊处理? 一般来说,hibernate会对一个preparedStatement做些什么样的处理?
先看preparedStatement是怎么创建的:
AbstractBatcher类中: prepareQueryStatement(String sql,boolean scrollable,ScrollMode scrollMode),最终在getPreparedStatement(final Connection conn,String sql,boolean scrollable,final boolean useGetGeneratedKeys,final String[] namedGeneratedKeys,final ScrollMode scrollMode,final boolean callable)方法里看到由connection.prepareStatement
不过这里面看点不少:
1, 对生成的sql有这么一个操作: sql = interceptor.onPrepareStatement( sql ); 默认情况是一个空的EmptyInterceptor,什么也不做.
2, 有scrollable和callable的选择.
3, 有useGetGeneratedKeys的判断 ==> GetGeneratedKeysHelper.prepareStatement( conn, sql );可GetGeneratedKeysHelper类里看出JDBC对某些方法是否支持.
4, namedGeneratedKeys != null与否判断 ==> NamedGeneratedKeysHelper.prepareStatement( conn, sql, namedGeneratedKeys ),与上相似是对JDBC一些方法的判断.
5, 最终是JDBC编程中常见的方式: result = conn.prepareStatement( sql ), 这也是问题context里生成preparedStatement的语句.
preparedStatement生成后做的一些设置:
1, setStatementFetchSize( ps );
2, 看到useLimit, 这么一个标志位, 这是干啥的? useLimit = useLimit( selection, dialect );是这样获得的. 现在是false的,也就不再深追.
3, 设置查询参数:
4, 如果 useLimit为false时, 设置setMaxRows( st, selection );不过,当前环境中没有设置.
上面设置完毕后, hibernate就直接到了出问题的语句上: ResultSet rs = ps.executeQuery();
这样得出结论: preparedStatement在创建过程和随后的设置过程中,并没有特殊处理.
-----
问题现场的PreparedStatement信息如下图所示:
写到这里, 一个有些恐惧的疑问出现了: 难道说项目中所用apache的dbcp包对问题有影响? 毕竟这里看到都是dbcp的实例,而自己所写例子没有用到这个dbcp.
------------
这篇帖子的标题,用了"续一"这样的字眼, 说实话,打心眼儿里想顺着这个问题也看看dbcp的源码,但有些办不从心了,还是就些打住,日后再做了断吧.