Hibernate是怎样实现呢?主要是依据反射机制。

现在以一次数据库查询操作分析Hibernate实现原理。

假设有一个用户表(tbl_user),表中字段有id,name,sex。同时有一个实体类(User)与其相对应,查询语句是:  select * from User。

1.在项目启动时,Hibernate配置文件中的内容已经存储在容器中,存储着表与实体中的关系。

2.在执行select * from User 时,会根据反射机制先找到User的全路径名称,进而找到容器中User对应的配置。

3.由于配置文件中的实体属性与数据库中的字段是对应的,Hibernate会将select * from User 这个hql语句根据不同的数据库方言解析成不同的SQL语句(select * from tbl_user)。

大致过程就是这样,当然,器内部实现的具体过程是比较复杂的,在使用Hibernate进行数据库操作时,应注意级联、延迟加载、缓存的使用。

简单来说就是,利用反射原理,将实体类中的字段按照xml配置或者annotation解析成一条或者多条sql语句,然后放入数据库执行,说的简单点,就是这么个原理,但是内部实现比较复杂.

原理:

1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件

2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息

3.通过config.buildSessionFactory();//创建SessionFactory

4.sessionFactory.openSession();//打开Sesssion

5.session.beginTransaction();//创建事务Transation

6.persistent operate持久化操作

7.session.getTransaction().commit();//提交事务

8.关闭Session

9.关闭SesstionFactory

这个就是原理,不是流程。主要就是一个基于JDBC的主流持久化框架,一个优秀的ORM实现,对JDBC访问数据库的代码做了封装,很大程度上监护了DAO层的编码工作。

hibernate缺点:

总的来说,hibernate的缺点主要有以下几点:

一、由于对持久层封装过于完整,导致开发人员无法对SQL进行优化,无法灵活使用JDBC的原生SQL,Hibernate封装了JDBC,所以没有JDBC直接访问数据库效率高。要使用数据库的特定优化机制的时候,不适合用Hibernate

二、框架中使用ORM原则,导致配置过于复杂,一旦遇到大型项目,比如300张表以上,配置文件和内容是非常庞大的,另外,DTO满天飞,性能和维护问题随之而来

三、如果项目中各个表中关系复杂,表之间的关系很多,在很多地方把lazy都设置false,会导致数据查询和加载很慢,尤其是级联查询的时候。

四、Hibernate在批量数据处理时有弱势,对于批量的修改,删除,不适合用Hibernate,这也是ORM框架的弱点

Hibernate是ORM框架(object-relation maping对象关系映射),它是用来实现JDBC的功能,但是它不能替换JDBC,它是在JDBC基础上实现的,即Hibernate中已经把JDBC封装了,最终的代码是到HIbernate在传递到JDBC在于数据库交换,所以性能没有JDBC直接与数据库交互快.

延迟加载:

一.什么是懒加载?他的作用?

延迟加载,也叫懒加载,它是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。

Hibernate中主要是通过代理(proxy)机制来实现延迟加载。它的具体过程:Hibernate丛数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据,hibernate并不是数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都是默认值;只有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据,这样在某些情况下,就可以提高查询效率。

有如下程序代码:

User user=(User)session.load(clazz, id);//直接返回的是代理对象

System.out.println(user.getId());//没有发送sql语句到数据库加载

user.getName();//创建真实的User实例,并发送sql语句到数据库中

注意:1.不能判断User=null;代理对象不可能为空

代理对象的限制:和代理关联的session对象,如果session关闭后访问代理则抛异常。session关闭之前访问数据库

2.getId()方法不行因为参数为ID,getClass()方法不用访问数据库就可以得到的数据

Hibernate中默认采用延迟加载的情况主要有以下几种

1,当调用session上的load()加载一个实体时,会采用延迟加载。

2,当session加载某个实体时,会对这个实体中的集合属性值采用延迟加载

3当session加载某个实体时,会对这个实体所有单端关联的另一个实体对象采用延迟加载。

二.关闭延迟加载

延迟加载确实会给程序的查询效率带来好处,但有时明确知道数据需要立即加载,如果Hibernate先默认使用延迟加载,而后又必须去数据库加载,反而会降低效率

1.     加载单个实体,如果不需要延迟加载,就可以使用session的get()方法。

2.     当session加载某个实体时,不需要对这个实体中的集合属性值延迟加载,而是要立即加载。这是可以在映射文件中这个集合的配置元素(set bag list)添加属性lazy=false;

3.     当session加载某个实体时,不需要对这个实体所单端关联的另一个实体对象延迟加载,就可以在影射文件中针对这个单端关联的配置元素(<one-to-one><many-to-one>)添加lazy=false;

能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。

hibernate的实现原理以及延迟加载的更多相关文章

  1. Hibernate(2)——Hibernate的实现原理总结和对其模仿的demo

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: 开源框架的学习思路(个人总结) Hibernate的运行原理总结 Hibernate实现原理中的两个主要技术 ...

  2. hibernate的工作原理

    hibernate的工作原理1.Hibernate 的初始化.读取Hibernate 的配置信息-〉创建Session Factory1)创建Configeration类的实例.它的构造方法:将配置信 ...

  3. Hibernate的工作原理及使用的原因

    一.工作原理: 1.读取并解析配置 2.读取并解析映射信息,创建Session Factory 3.打开Session 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Sess ...

  4. Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)

    假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下: 假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: Session session=H ...

  5. Hibernate的ORM原理和实现

    >>Hibernate和ORM ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样 ...

  6. Hibernate二级缓存原理

    缓存:缓存是什么,解决什么问题? 位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为缓存Cache.缓存目的:让数据更接近于应用程序,协调速度不匹配,使访问速度更快 ...

  7. HIbernate学习笔记4 之 延迟加载和 关联映射

    一.延迟加载 * 在使用hibernate一些方法的查询数据的时候,返回的只是一个空对象(除id外属性都为NULL),并没有真正的查询数据库,而是在使用这个对象时才会触发查询数据库,并将这些数据注入到 ...

  8. 2018.10.7 理解Hibernate的工作原理及其中的ORM详解

    复习 hibernate框架 简介j及其搭建: hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC做了轻量级的封装,而我们java程序员可以使用面向对象的思想来操纵数据库. 1 ...

  9. Hibernate中多种方式解除延迟加载

    问题引发:因为dao使用load(),默认延迟加载的,当在biz关闭session之后,UI层无法获取对象的非id属性值 解决方案: 1.变成get,即时加载 2.用Hibernate.isIniti ...

随机推荐

  1. quartz 任务时间调度入门使用

    这一小节主要是针对cronschedule用法进行讨论,首先讲一下cronschedule基础知识点: 一个cronschedule至少有6个字符(或者7个字符),空格作为间隔,比如 0 * * * ...

  2. ch 与等宽字体

    难题 有的时候,特别想通过字符来判断元素的长度,比如: 多行文本溢出时,文字变省略号 文字一个个的显示 效果分别如下: 第一种情况下,如果可以通过字符的数量判断长度是否溢出,从而把最后几个字符替换成省 ...

  3. Nginx设置网站维护页面

    网站升级需要停服,可以在Nginx设置静态页面设置强制跳转 修改nginx配置文件nginx.conf http { sendfile on; keepalive_timeout 65; server ...

  4. Linq 多连接及 left join 实例 记录

    var retList = from d in mbExList.Cast<MaterialBaseEx>().ToList() join c in umcList.Cast<Cla ...

  5. HashMap 的工作原理及代码实现,什么时候用到红黑树

    HashMap工作原理及什么时候用到的红黑树: 在jdk 1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.但是当位于一个桶中的元素较多,即has ...

  6. mysql jdbc操作

    import java.sql.*; import java.util.Map; public class Mysql { public static void main(String[] args) ...

  7. jquery报错:“ReferenceError: jQuery is not defined”

    这明显是没有引到jquery,原因就是jquery没有放在最前面,jquery应该最先引入.

  8. java 8 学习资料

    出处: 总览 http://www.importnew.com/24300.html stream api 详解 : https://www.ibm.com/developerworks/cn/jav ...

  9. extjs中的store

    1.store中重要的属性和方法 属性:data.proxy.reader.url.root .... 方法:load 2.理解:data--原料,proxy--运输车,reader--加工厂,sto ...

  10. 泛型T和通配符?的区别

    这里如果是泛型T的话,那么创建该类的时候就需要指定类型,而通配符不需要.