hibernate的实现原理以及延迟加载
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的实现原理以及延迟加载的更多相关文章
- Hibernate(2)——Hibernate的实现原理总结和对其模仿的demo
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: 开源框架的学习思路(个人总结) Hibernate的运行原理总结 Hibernate实现原理中的两个主要技术 ...
- hibernate的工作原理
hibernate的工作原理1.Hibernate 的初始化.读取Hibernate 的配置信息-〉创建Session Factory1)创建Configeration类的实例.它的构造方法:将配置信 ...
- Hibernate的工作原理及使用的原因
一.工作原理: 1.读取并解析配置 2.读取并解析映射信息,创建Session Factory 3.打开Session 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Sess ...
- Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)
假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下: 假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: Session session=H ...
- Hibernate的ORM原理和实现
>>Hibernate和ORM ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样 ...
- Hibernate二级缓存原理
缓存:缓存是什么,解决什么问题? 位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为缓存Cache.缓存目的:让数据更接近于应用程序,协调速度不匹配,使访问速度更快 ...
- HIbernate学习笔记4 之 延迟加载和 关联映射
一.延迟加载 * 在使用hibernate一些方法的查询数据的时候,返回的只是一个空对象(除id外属性都为NULL),并没有真正的查询数据库,而是在使用这个对象时才会触发查询数据库,并将这些数据注入到 ...
- 2018.10.7 理解Hibernate的工作原理及其中的ORM详解
复习 hibernate框架 简介j及其搭建: hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC做了轻量级的封装,而我们java程序员可以使用面向对象的思想来操纵数据库. 1 ...
- Hibernate中多种方式解除延迟加载
问题引发:因为dao使用load(),默认延迟加载的,当在biz关闭session之后,UI层无法获取对象的非id属性值 解决方案: 1.变成get,即时加载 2.用Hibernate.isIniti ...
随机推荐
- yii---往对象里面添加属性
我们在用YII的时候,查询到一条数据,但是很多时候会往这条查询的数据里,添加某个字段,但是直接添加会报错: $thread = $this->getThreadService()->get ...
- 百度地图InfoWindow弹窗圆角
效果如下 使用CSS样式 /*地图标题*/ .BMap_pop div:nth-child(1) div { border-radius: 8px 0 0 0; } .BMap_pop div:nth ...
- java 多线程研究:锁的概念
java多线程:锁 java的多线程中的锁是干嘛的呢?在网上找了很多博客,大都是很专业的语言,让我一时间摸不着头脑.下面分三个部分来总结多线程中的锁的概念. 一,基础概念: 多线程在运行的时候可能会遇 ...
- 【转】C#线程篇
C# 温故而知新: 线程篇(一) C# 温故而知新: 线程篇(二) C# 温故而知新:线程篇(三) C# 温故而知新: 线程篇(四)
- 计蒜客 31001 - Magical Girl Haze - [最短路][2018ICPC南京网络预赛L题]
题目链接:https://nanti.jisuanke.com/t/31001 题意: 一带权有向图,有 n 个节点编号1~n,m条有向边,现在一人从节点 1 出发,他有最多 k 次机会施展魔法使得某 ...
- MySQL命令:创建数据库、插入数据
简介: 学习mysql环境为ubantu,下面记录一些基本的创建数据库和插入数据的口令 打开MySQL 服务并使用 root 登录: --打开 MySQL 服务 sudo service mysql ...
- Python:zip()函数
zip()函数的定义 从参数中的多个迭代器取元素组合成一个新的迭代器: 返回:返回一个zip对象,其内部元素为元组:可以转化为列表或元组: 传入参数:元组.列表.字典等迭代器. zip()函数的用法 ...
- linux:查找搜索文件
学习内容来源: 实验楼链接: https://www.shiyanlou.com/ 与搜索相关的命令常用的有 whereis,which,find 和 locate . whereis 简单快速 $w ...
- 多态设计 zen of python poem 显式而非隐式 延迟赋值
总结 1.python支持延迟赋值,但是给调用者带来了困惑: 2.显式而非隐式,应当显式地指定要初始化的变量 class Card: def __init__(self, rank, suit): s ...
- 【xargs -i】复制文件夹中前100个文件
复制前一万个文件到 tmp 下 |xargs -i cp {} /tmp 复制后一万个文件到 tmp 下 |xargs -i cp {} /tmp 查看linux下文件夹文件数目 ls -l |gre ...