Hibernate4实战 之第六部分:基本实现原理

总体流程
1:经过configuration来读cfg.xml文件
2:获得SessionFactory 工厂
3:经过SessionFactory 工厂来建立Session实例
4:经过Session打开事务
5:经过session的api操做数据库
6:事务提交
7:关闭链接
 
说明:如下分方法描述的实现流程并非Hibernate的完整实现流程,也不是Hibernate的完整实现顺序,只是描述了Hibernate实现这些方法的主干和基本方式,主要是用来理解这些方法背后都发生了些什么,若是须要详细完整的实现流程,请查阅Hibernate相应文档和源代码
 当咱们调用了session.save(UserModel)后:
1:TO--->PO: Hibernate先在缓存中查找,若是发如今内部缓存中已经存在相同id的PO,就认为这个数据已经保存了,抛出例外。
若是缓存中没有,Hibernate会把传入的这个TO对象放到session控制的实例池去,也就是把一个瞬时对象变成了一个持久化对象。
若是须要Hibernate生成主键值,Hibernate就会去生成id并设置到PO上
2:客户端提交事务或者刷新内存
3:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
4:根据hbm.xml文件和model来动态的拼sql,以下:
insert into 表名(来自hbm.xml) (字段名列表(来自hbm.xml )) values(对应的值的列表(根据hbm.xml从传入的model中获取值))
5:真正用JDBC执行sql,把值添加到数据库
6:返回这个PO的id。
 
当咱们调用了session.update(UserModel)后:
1:DO--->PO:首先根据model 的主键在hibernate的实例池中查找该对象,找到就抛出错误。
若是没有就DO--->PO,Hibernate会把传入的这个DO对象放到session控制的实例池去,也就是把一个瞬时对象变成了一个持久化对象
2:客户端提交事务或者刷新内存
3:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
4:根据hbm.xml文件和model来动态的拼sql,不进行脏数据检查,以下:
update 表名(来自hbm.xml) set 字段名(来自hbm.xml )=值(根据hbm.xml从传入的model中获取值) where 条件
5:真正用JDBC执行sql,把值修改到数据库
 
当咱们调用了session.update(UserModel)后:

1:首先根据model 的主键在hibernate的实例池中查找该对象,找到就使用该PO对象(用来检查脏数据)。
2:客户端提交事务或者刷新内存
3:Hibernate会进行脏数据检查,若是没有数据被修改,就不执行下面的步骤了。
4:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
5:根据hbm.xml文件和model来动态的拼sql,进行脏数据检查(若是开启了dynamic-update的话),以下:
update 表名(来自hbm.xml) set 字段名(来自hbm.xml )=值(根据hbm.xml从传入的model中获取值) where 条件
6:真正用JDBC执行sql,把值修改到数据库
 
Id的生成方式为assigned的状况
当咱们调用了session.delete(UserModel)后:
1:根据model的主键在数据库里面查找数据,来保证对象的存在,而后把找到的对象放到内存里面,若是此时在hibernate的实例池中已经存在对应的实体对象(注意:代理对象不算实体对象),就抛出例外。
2:若是此时在hibernate的实例池中不存在对应的实体对象,那么就把对象放到内存里面,但会标识成待删除的对象,就不能够被load等使用了。
3:若是对象仍是不存在,那么就直接返回了(注意,这个时候是不抛出例外的)。也就是说,delete以前会执行一个查询语句。
4:客户端提交事务或者刷新内存
5:判断待删除的PO是否存在,存在才须要删除,不然不须要删除
6:若是要删除,才执行如下的步骤。先根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
7:根据hbm.xml文件和model来动态的拼sql,以下:
delete from 表名(来自hbm.xml) where 主键=值(来自model)
8:真正用JDBC执行sql,把数据从数据库中删除
 
Id的生成方式为非assigned的状况
n当咱们调用了session.delete(UserModel)后:
1:根据model的主键在hibernate的实例池中查找对应的实体对象(注意:代理对象不算实体对象),找到就抛出例外。
2:若是内存中没有对应的实体对象,就什么都不作。
3:客户端提交事务或者刷新内存
4:先根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
5:根据hbm.xml文件和model来动态的拼sql,以下:
delete from 表名(来自hbm.xml) where 主键=值(来自model)
6:真正用JDBC执行sql,把数据从数据库中删除,若是数据不存在,就抛出例外
当咱们调用了session.delete(UserModel)后:
1:根据model的主键在hibernate的实例池中查找对应的实体对象(注意:代理对象不算实体对象),找到就使用该对象。
2:若是内存中没有对应的实体对象,就到数据库中查找来保证对象的存在,把找到的对象放到内存里面,并且不会标识成待删除的对象,能够继续被load等使用。代理对象也须要去数据库中查找数据。
3:若是对象仍是不存在,那么就抛出例外。也就是说,delete以前可能会执行一个查询语句。
4:客户端提交事务或者刷新内存
5:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
6:根据hbm.xml文件和model来动态的拼sql,以下:
delete from 表名(来自hbm.xml) where 主键=值(来自model)
7:真正用JDBC执行sql,把数据从数据库中删除
当咱们调用了s.load(UserModel.class, “主键值");后:
1:根据model类型和主键值在一级缓存中查找对象,找到就返回该对象
2:若是没有找到,判断是否lazy=true,若是是,那就生成一个代理对象并返回;不然就先查找二级缓存,二级缓存没有,就查找数据库。若是是返回代理对象的,在第一次访问非主键属性的时候,先查找二级缓存,二级缓存中没有才真正查找数据库。
3:若是须要查找数据库的话,会根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
4:根据hbm.xml文件和model来动态的拼sql,以下:
select 字段列表(来自hbm.xml) from 表名(来自hbm.xml) where 主键=值
5:真正用JDBC执行sql,把数据从数据库中查询出来到rs里面。若是找不到就报错
6:从结果集---〉Model,而后返回model
 
注意:load方法开不开事务均可以执行查询语句。

 
当咱们调用了s.get(UserModel.class, “主键值");后:
1:先根据model类型和主键值查找缓存,若是存在具体的实体对象,就返回;若是存在实体的代理对象(好比前面load这条数据,可是尚未使用,那么load生成的是一个只有主键值的代理对象),那么查找数据库,把具体的数据填充到这个代理对象里面,而后返回这个代理对象,固然这个代理对象此时已经彻底装载好数据了,跟实体对象没有什么区别了。
2:若是要查找数据库,先根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
3:根据hbm.xml文件和model来动态的拼sql,以下:
select 字段列表(来自hbm.xml) from 表名(来自hbm.xml) where 主键=值
4:真正用JDBC执行sql,把数据从数据库中查询出来到rs里面,没有值就返回null
5:从结果集---〉Model,而后返回model
 
注意:get方法开不开事务均可以执行查询语句。
 
当咱们调用了q.list();后:
1:对HQL进行语义分析,分析出model来
2:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
3:根据hbm.xml文件和model,来解析HQL,从而实现动态的把HQL转换成对应的sql,(从hql---〉sql这个过程是很是复杂的,不但区分不一样的数据库,还包括了对sql进行自动的优化),这里只能简单的示例以下:
select 字段列表(来自hbm.xml) from 表名(来自hbm.xml) where 条件
4:真正用JDBC执行sql,把数据从数据库中查询出来到rs里面
5:从结果集---〉Model集合(或对象数组),而后返回model集合(或对象数组)
 
注意:list()方法开不开事务均可以执行查询语句。
 原创内容 转自请注明【  http://sishuok.com/forum/blogPost/list/2483.html#7182
视频配套PPT,视频地址【  Hibernate4实战-独家视频课程 】
相关文章
相关标签/搜索