`
flash59
  • 浏览: 96180 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate 数据保存操作的原理

阅读更多
数据的保存,更新和删除:
   1Session.save()方法:
Session.save()方法用于实体对象的持久化保存,也就是说当执行session.save()方法时会生成对应的insert SQL语句,完成数据的保存。如下面的代码:
User user=new User();
user.setName(“zx”);
Transaction tx=session.beginTransaction();
session.save(user);
tx.commit();
当执行到session.save()方法时,Hibernate并不会马上生成insert SQL语句来进行数据的保存,而是当稍后清理session的缓存时才有可能执行insert SQL语句,那么session.save()方法到底会执行哪些步骤呢?请看进行了如下总结:
一、           session的内部缓存中寻找保存对象,如果找到了,则认为此数据已经保存(曾经执行过insert操作),实体对象已经处于persistent状态,直接返回。此时即使数据相比之前的状态发生了变化,也将在事务提交时由脏数据检查来判定是否需要执行update操作。
二、           如果实体对象实现了lifecycle接口,那么将执行待保存对象的onSave()方法。
三、           如果实体对象实现了Validatable接口,那么将会执行相应的validate()方法。
四、           如果存在拦截器对象,那么将会执行Interceptor.onSave()方法。
五、           构造insert SQL语句完成数据保存。
六、           数据保存成功后,设定实体对象的id为插入记录的id
七、           将保存后的实体对象纳入Hibernate的内部缓存(一级缓存)。注意Hibernate不会把保存后的实体对象纳入二级缓存,因为刚刚保存过的实体对象很可能在之后被修改,缓存的频繁更新以及带来的同步问题代价,超出了缓存该对象所带来的收益。
八、           最后如果该对象有关联对象,那么将会递归处理该级联对象。
 
1、      Session.update()方法:
  前面我在实体对象状态转化部分曾经讲过,session.update()方法能够将一个处于游离状态的对象,重新纳入Hibernate的内部缓存,变成持久化对象。如下面的代码:
Configuration cfg = new Configuration();
SessionFactory sf=cfg. configure().buildSessionFactory();
Customer customer=new Customer(“zx”,27,images);//customer对象处于自由状态
Session session=sf.openSession();
 
Transaction tx=session.beginTransaction();
session.save(customer);//保存后customer对象处于持久化状态
session.flush();//清空缓存后customer对象处于游离状态
tx.commit();
session.close();
 
Session session2=sf.openSession();
Transaction tx2=session2.beginTransaction();
session2.update(customer);//通过调用update()方法将游离状态的customer对象,再次转化成持久化状态
session2.delete(customer);//调用delete()方法后,当清空缓存时,会将customer对象移出缓存,同时会在数据库中生成delete事务,来删除customer对象对应的数据记录
tx.commit();
session.close();
那么这个方法到底执行了哪些步骤呢?它会按照下面的步骤进行操作:
一、           首先会在缓存中寻找需要更新的实体对象,如果找到就立刻返回,从这里我们可以看出如果对一个已经处于persistent的实体对象执行update()方法,将不会产生任何作用。
二、           然后当提交事务进行缓存清理时,将会通过脏数据检查,确定变化的属性,然后生成update SQL语句完成数据的更新。
这里有一个问题我们要强调一下,那就是只要通过update()方法将一个游离对象与session相关联,那么不论这个游离的实体对象的属性是否发生改变,都会执行update SQL语句。如下面的代码:
 
Transaction tx=session.beginTransaction();
session.update(customer);
tx.commit();
session.close();
在这段代码中并没有修改customer对象的任何属性值,但是也会执行一个update SQL语句,如果你希望在没有改变实体对象属性值的情况下不去执行update SQL语句,那么你要开启实体对象<class>元素的”select-before-update”属性,将其设置为”true”,这个属性默认为”false”。如下进行配置:
<class name=”com.neusoft.entity.Customer” table=”customer” select-before-update=”true”>
如果启用了这个属性配置,那么在清理session缓存之前,会首先执行类似如下的一条SQL语句:
Select * from customer where id=’1’;
查询处所有的customer实体在数据库中对应的属性值,然后逐条与缓存中属性值进行比较,如果发生了改变,那么将会生成update操作进行数据更新,如果没有发生改变那么将不会进行update操作。要跟据实际需求情况来决定是否开启这个选项,如果实体对象的属性不会经常发生改变,那么就应该开启这个选项,以免执行多余的update操作。如果实体对象的属性会经常发生改变,那么就没必要开启这个选项,以免在执行update操作前再执行多余的select语句。
 
注:(1)、当执行对一个游离实体对象执行session.update()操作时,如果在数据库中不存在这个实体对应的纪录,那么这个操作将会抛出异常。
   2)、当执行session.update()方法将一个游离对象与session关联时,如果此时在缓存中已经存在了与该实体对象具有相同OID的持久化对象,那么这个方法会抛出异常。如下面代码:
Customer customer1=new Customer(“1”,“zx”,27,images);
Session session1=sf.openSession();
Transaction tx=session1.beginTransaction();
session.save(customer1);
session.flush();
tx.commit();
session1.close();
 
Session session2=sf.openSession();
Transaction tx2=session2.beginTransaction();
Customer othercustomer=(Customer)session2.load(Customer.class,”1”);
session2.update(customer1)
tx2.commit();
session2.close();
当再次将游离对象customer1session2关联时,此时因为load()操作,在缓存已经加载了一个和customer1具有相同OIDothercustomer对象,此时由于Hibernate缓存的对象缓存机制不允许把OID相同的对象缓存,所以会抛出异常。
2、      Session.saveOrUpdate():
这个方法包含了save()方法和update()方法的特点,如果传入该方法的是一个游离对象,那么这个方法就会执行update操作,如果传入该方法的是一个临时对象,那么这个方法就会执行insert操作。这个方法幕后的工作原理如下:
a)        首先在缓存寻找,如果找到待保存的操作就直接返回。
b)        如果实体实现了拦截方法,那么就执行isUnsaved()方法,判断实体对象状态。
c)        如果实体处于临时状态就执行save(),如果实体处于游离状态那么就执行update()
这里存在一个问题,那就是Hibernate是怎样判断一个实体是处于游离态还是临时状态的?如果实体满足下面的一个条件,就认为这个实体处于临时状态。
.Java对象的OID值为null
.如果Java对象具有version属性(将在并发加锁部分讲解)且为null
.如果实体的<id>设置了属性unsaved-value,而且OID值与unsaved-value值相等。
.如果实体的version属性设置了unsaved-value,并且version属性的值与unsaved-value值相等。
.如果实体实现了Interceptor,而且Interceptor.isUnsaved()方法返回true
满足这些条件中的一个,这个实体就被认为是临时对象。
3、      Session.delete():
delete()方法用于从数据库中删除一个或一批实体所对应的数据,如果传入的对象是持久化对象,么当清理缓存时,就会执行delete操作。如果传入的是游离对象,那么首先会使该对象与session相关联,然后当清理缓存时,再执行delete操作。看如下代码:
Session session=sessionFactory().openSession();
Transaction tx=session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,”1”);
session.delete(customer);//计划执行一条delete语句
tx.commit();//清理缓存,执行一条delete语句
session.close();//关闭session,这时将会把customer对象从缓存中删除。
如果上面的代码中的customer对象是一个游离对象,那么当执行session.delete()方法时,会首先将游离的customer对象与session相关联,然后再清理缓存时,再执行delete操作。如果你想一次删除多条数据,那么可以采用一个重载的delete()方法:delete(“from Customer c where c.id>’8’ ”);这个方法可以删除符合条件的所有数据。
分享到:
评论

相关推荐

    jsp hibernate 数据保存操作的原理.docx

    jsp hibernate 数据保存操作的原理.docx

    jsp hibernate 数据保存操作的原理

    当执行到session.save()方法时,Hibernate并不会马上生成insert SQL语句来进行数据的保存,而是当稍后清理session的缓存时才有可能执行insert SQL语句,那么session.save()方法到底会执行哪些步骤呢?

    Hibernate_test

    Hibernate对象关系映射,基本工作原理是将对象数据保存到关系数据库的表中,以及将关系数据库中数据读入到对象中。

    Hibernate实战(第2版 中文高清版)

     3.3.5 运行时操作元数据   3.4 其他实体表示法   3.4.1 创建动态的应用程序   3.4.2 表示XML中的数据   3.5 小结  第二部分 映射概念和策略  第4章 映射持久化类   4.1 理解实体和值类型   4.1.1 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     1.2.2 关系数据模型  1.2.3 域模型  1.2.4 域对象  1.2.5 域对象之间的关系  1.2.6 域对象的持久化概念  1.3 小结  1.4 思考题 第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  ...

    hb_hibernate_05

    Hibernate对象关系映射,基本工作原理是将对象数据保存到关系数据库的表中,以及将关系数据库中数据读入到对象中。

    hb_hibernate

    Hibernate对象关系映射,基本工作原理是将对象数据保存到关系数据库的表中,以及将关系数据库中数据读入到对象中。

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     1.2.2 关系数据模型  1.2.3 域模型  1.2.4 域对象  1.2.5 域对象之间的关系  1.2.6 域对象的持久化概念  1.3 小结  1.4 思考题 第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     1.2.2 关系数据模型  1.2.3 域模型  1.2.4 域对象  1.2.5 域对象之间的关系  1.2.6 域对象的持久化概念  1.3 小结  1.4 思考题 第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     1.2.2 关系数据模型  1.2.3 域模型  1.2.4 域对象  1.2.5 域对象之间的关系  1.2.6 域对象的持久化概念  1.3 小结  1.4 思考题 第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  ...

    JBoss Seam 工作原理、seam和hibernate的范例、RESTFul的seam、seam-gen起步、seam组件、配置组件、jsf,jboss、标签、PDF、注解等等

    1.2.2. 工作原理........................................................................................................................................................... 26 1.3. Seam 中的可点击列表:...

    达内java培训目录

    • DMS 服务器端接收到日志数据,将日志数据备份保存为文件数据,并存入数据库。 4.开班3个月内,贯穿Web前端技术和Servlet/JSP的学习,将完成T-NetCTOSS项目: NetCTOSS系统的主要任务是提供对于数据的计费查询和...

    从J2SE到J2EE知识点介绍

    1. 保存数据(源代码:hibernate_0100) 204 2. 删除数据(源代码:hibernate_0200) 205 3. 更新数据(源代码:hibernate_0300) 207 4. 加载数据(源代码:hibernate_0400) 208 5. 缓存 211 6. 对象映射配置 212 ...

    java面试题

    Hibernate工作原理,Hibernate数据持久化? 答:Hibernate工作原理: 1:读取并解析映射信息,创建SessionFactory 2:打开Session 3:创建事物 4:持久化操作 5:提交事务 6:关闭Session 7:关闭...

    Spring面试题

    -(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中; -(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法; -(4)如果...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    我们掌握了数据库及其应用技术、数据库原理、计算机网络技术等课程,对数据库的设计、应用、维护及局域网的组成有了深刻的认识与一定的动手实践能力,考取了信息处理、程序设计、数据库技术等国家IT认证。...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    3.7.2 application中数据的操作 3.7.3 Web应用初始化参数的配置 3.7.4 application对象应用示例 3.8 其他内置对象的应用 3.8.1 应答与请求的page对象 3.8.2 页面上下文的page Context对象 3.8.3 获取web.xml配置信息...

Global site tag (gtag.js) - Google Analytics