热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

详解hibernate4基本实现原理

本文通过图文并茂的形式给大家介绍的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的情况

当我们调用了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()方法开不开事务都可以执行查询语句。



总结

以上所述是小编给大家介绍的hibernate4基本实现原理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 本文探讨了如何利用 Hibernate 进行高效的批量更新和删除操作,包括直接使用 Hibernate API 的方法及其局限性,以及如何通过 JDBC 或存储过程实现更优的性能。 ... [详细]
  • 作为一名Java Web开发新手,我在尝试将项目部署至Tomcat服务器并连接MySQL数据库时遇到了驱动加载失败的问题。经过一番排查和努力,最终找到了解决方案。 ... [详细]
  • sqlserver动态分区方案例子
    sqlserver动态分区方案例子当我们存储的数据量比较大时,比如超过千万,上亿级别时单纯的使用索引可能效果不明显了,此时我们可以考虑采 ... [详细]
  • 本文探讨了随着并发需求的增长,MySQL数据库架构如何从简单的单一实例发展到复杂的分布式系统,以及每一步演进背后的原理和技术解决方案。 ... [详细]
  • 深入理解Java MySQL数据库连接池实现
    尽管利用Apache Commons DBCP等工具可以轻松构建数据库连接池,但本文详细解析了数据库连接池的工作机制,提供了详尽的注释,帮助开发者深入理解其内部运作。这不仅有助于提高数据库操作的效率,还能增强应用程序的稳定性和性能。 ... [详细]
  • 本文探讨了在H2内存数据库中使用to_char函数遇到的问题,包括别名创建失败和堆栈内存溢出的情况,并提供了解决方案。 ... [详细]
  • 本文深入探讨网页游戏的开发流程,涵盖从程序框架设计到具体实现的技术细节,旨在为开发者提供全面的指导。 ... [详细]
  • GBase 8s SQL 指南:多列约束详解
    本文档详细介绍了如何在GBase 8s中使用多列约束格式,将其应用于现有表的一列或多列。这种格式类似于CREATE TABLE语句中的多列约束,但提供了一些额外的选项,如INDEX DISABLED关键字。 ... [详细]
  • PySpark实战:高效使用DataFrame超越RDD
    本文深入探讨了PySpark中DataFrame的使用方法及其相对于传统RDD的优势,旨在帮助开发者更好地理解和利用这一强大工具。 ... [详细]
  • 今天发现Mysql的主从数据库没有同步先上Master库:mysqlshowprocesslist;查看下进程是否Sleep太多。发现很正常。showmaster ... [详细]
  • 本文总结了WebSphere应用服务器出现宕机问题的解决方法,重点讨论了关键参数的调整,包括数据源连接池、线程池设置以及JVM堆大小等,旨在提升系统的稳定性和性能。 ... [详细]
  • 本文探讨了Java编程中MVC模式的优势与局限,以及如何利用Java开发一款基于鸟瞰视角的赛车游戏。 ... [详细]
  • 尽管PHP是一种强大且灵活的Web开发语言,但开发者在使用过程中常会陷入一些典型的陷阱。本文旨在列出PHP开发中最为常见的10种错误,并提供相应的预防建议。 ... [详细]
  • 基于Java的学生宿舍管理系统设计
    本论文探讨了如何利用Java技术设计和实现一个高效的学生宿舍管理系统。该系统旨在提高宿舍管理的效率,减少人为错误,同时增强用户体验。通过集成用户认证、数据管理和查询功能,系统能够满足学校宿舍管理的多样化需求。 ... [详细]
  • 本文介绍了MySQL数据库的安全权限管理思想及其制度流程,涵盖从项目开发、数据库更新到日常运维等多个方面的详细流程控制,旨在通过严格的流程管理和权限控制,有效预防数据安全隐患。 ... [详细]
author-avatar
手机用户2502917943
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有