hibernate的实现原理以及延迟加载

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

      如今以一次数据库查询操做分析Hibernate实现原理。数据库

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

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

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

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

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

            

简单来讲就是,利用反射原理,将实体类中的字段按照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的缺点主要有如下几点:

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

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

3、若是项目中各个表中关系复杂,表之间的关系不少,在不少地方把lazy都设置false,会致使数据查询和加载很慢,尤为是级联查询的时候。

4、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关闭后,再访问懒加载的对象将出现异常。

相关文章
相关标签/搜索