Hibernate(十八): Hibernate初始化时如何生成SQL语句?

    昨天看Hibernate方面书时又看到了"dynamic -update =true"的配置. 在一个Model类的Mapping中设置它后, hibernate在初始化时就不再为此Model类生成更新语句了, 默认是生成的(至于什么情况下设置此选择这个问题,这里就不赘述了).也说不清什么原因, 突然想看下不设置此选项时,hibernate究竟怎么生成更新语句的, 毕竟眼见为实嘛,虽说以前无数次地见到书上/文档里/同事们都这么说.

    再加上自己向来对Hibernate源码研究情有独钟(请见Hibernate源码研究碎得整理(一到十三) ). 说实话,以前这样想看SQL是怎么生成的话题想不出,即使想出来也无从下手. N长时间的思考/折磨/挣扎/痛定思痛的沉淀后, 觉得自己现在可以试它一试了.

    环境搭建很简单,这里不再赘述. 这里以一个Model类来说明:Person类及Person.hbm.xml配置文件. Person类很简单就三个属性(id,name,age),配置文件也就很简单了.


    .......Eclipse下设置断点跟踪........
        1,生成一个Configuration对象时,没发现可疑代码.(心情log: 兴致勃勃,肯定能找到,见证这"辉煌时刻"吧!)
        2,解析hibernate.cfg.xml配置文件时,也没发现可疑代码. (心情log:配置文件解析完了,怎么还没有呢? 有些纳闷了:我要的代码,你在哪? 不过有收获:PersistentClass类里有这么个方法useDynamicUpdate,于是在这"布控"了断点,虽然现在还没生成想要的SQL 语句,不过,想信真正生成时hibernate会调用这个方法)
        3,由于上面在认为关键代码上"布控"了断点, 于是Eclipse中直接按了F8,不出所料在上面useDynamicUpdate方法时设置断点处停了下来. 原来是在Configuration在buildSessionFactory时给Person类生成一个EntityPersister时停的.于是, 集中看EntityPersister当前实现类的SingleTableEntityPersister的构造方法. 这个构造方法里先调用了父类AbstractEntityPersister的构造方法(父类构造方法很长,有300来行), 一步步跟踪看父类构造方法执行完了,还是看到SQL的生成,SQL生成这样的方法很公用的不用放到具体子类来执行吧? 父类构造方法中没发现,有些气馁了.
            再看子类构造方法(同样长,也是300行),   一步步执行,看到了很像的customSQLUpdate,但不是(这里记下来,这个属性代表什么?).  眼看要执行完了,还是没发现. 难道自己的猜测不对?  在子类构造方法最后一类,发现了这么一个方法调用 postConstruct.直觉告诉我,有戏! 再看它是父类里的方法,更坚定了信心. 于是, 情况朝对自己有利的方向发展了: 见到了sqlUpdateStrings(感觉像猎人发现了猎物的足迹),发现了顾名思义的方法generateUpdateString 调用! 接下来的事就水到渠成了.

            终于看到可爱的update语句了: update Person set name=?, age=? where id=?
    ............................................

    总结下发现updateSQL过程中的关键点,用兴趣的看官可设置断点体会下:
    1, 调用环境: 父类AbstractEntityPersister中的postConstruct方法.
    2, 最终生成: org.hibernate.sql.Update类中toStatementString方法.

    以上是updae语句的生成,其余insert/delete语句如出一辙,不过相应具体类换成了Insert/Delete.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值