当前位置:  编程技术>java/j2ee

jsp hibernate 数据保存操作的原理

    来源: 互联网  发布时间:2014-10-17

    本文导语:  数据的保存,更新和删除: 1、Session.save()方法: Session.save()方法用于实体对象的持久化保存,也就是说当执行session.save()方法时会生成对应的insert SQL语句,完成数据的保存。如下面的代码: User user=new User(); user.setName(“zx”); ...

数据的保存,更新和删除:
1、Session.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语句,那么你要开启实体对象元素的”select-before-update”属性,将其设置为”true”,这个属性默认为”false”。如下进行配置:

如果启用了这个属性配置,那么在清理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();
当再次将游离对象customer1与session2关联时,此时因为load()操作,在缓存已经加载了一个和customer1具有相同OID的othercustomer对象,此时由于Hibernate缓存的对象缓存机制不允许把OID相同的对象缓存,所以会抛出异常。
2、 Session.saveOrUpdate():
这个方法包含了save()方法和update()方法的特点,如果传入该方法的是一个游离对象,那么这个方法就会执行update操作,如果传入该方法的是一个临时对象,那么这个方法就会执行insert操作。这个方法幕后的工作原理如下:
a) 首先在缓存寻找,如果找到待保存的操作就直接返回。
b) 如果实体实现了拦截方法,那么就执行isUnsaved()方法,判断实体对象状态。
c) 如果实体处于临时状态就执行save(),如果实体处于游离状态那么就执行update()。
这里存在一个问题,那就是Hibernate是怎样判断一个实体是处于游离态还是临时状态的?如果实体满足下面的一个条件,就认为这个实体处于临时状态。
.Java对象的OID值为null。
.如果Java对象具有version属性(将在并发加锁部分讲解)且为null。
.如果实体的设置了属性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入门教程第1/3页
  • jsp hibernate的分页代码第1/3页
  • jsp Hibernate批量更新和批量删除处理代码
  • jsp Hibernate 函数简介
  • 如何把JSP生成的HTML保存在服务器端
  • 怎样利用JAVABEAN将JSP页面提交的数据保存到数据库,请给代码好吗?谢谢!
  • ?? 将jsp生成的页面保存成html ??
  • JSP如何保存用户信息?
  • 一书中讲到JSP作访问计数器是用文件保存计数,是否有不妥(预知详情请进)
  • 在JSP中有没有什么方法保存一个变量,直到一系列页面应用都关闭?
  • 简单!如果网页的内容为HTML标签和JAVASCRIPT代码,那应该将该文件保存为.jsp还是
  • servlet/jsp 中的session(会话)保存在系统的什么地方??可不可以直接修改?
  • 请问JAVA程序里如何在服务器端保存JSP生成的HTML页面
  • jsp如何保存图片到sqlserver
  • 急啊,怎样在一个jsp文件里保存connection,使得下一个网页不用再次打开数据库
  • 在forte for java 4的Source Editor中编辑jsp时候,可以输入中文,可是保存后关闭再打开,中文显示???,怎么回事啊
  • eidt.jsp对网页进行编辑,网页内容存放在数据库中,其中有些字段用textarea多行编辑框显示,保存提交数据库后,再次对它编辑,那些用多行
  • $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$在jsp中怎么保存/读取一个cookie??
  • jsp下载文件时文件名到客户端时乱码?就是保存的时候,望高手指点!
  • 怎样用oracle保存长字符串(4、5千字左右),并用jsp取出?在线给分
  • ajax+jsp草稿自动保存的实现代码
  • jsp action中保存和修改的关系
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • JSP怎么运行的?原理?
  • ?:jsp的运行机制或运行原理是如何的,who能给我一个解释,谢谢!
  • JSP中实现系统登录后的退出原理及代码
  • JSP开发入门(二)----JSP语法的基本原理
  • JSP运行原理和九大隐式对象说明
  • 有关JavaBean中的资源释放问题,(熟悉jsp+JavaBean原理的高手请进)
  • jsp自定义标签技术(实现原理与代码以及平台搭建步骤)
  • JSP中清空cookie代码参考
  • 现有1.jsp、2.jsp、3.jsp三个文件,我怎么在3.jsp文件中得到1.jsp中输入的值?
  • 一个框界网爷包含上下两个网页a1.jsp和a2.jsp,怎么实现a1.jsp自身不变且提交数据到下面的a2.jsp呢?不胜感激,急..
  • 请问jsp和serlet之间怎么通讯,jsp和jsp之间呢?
  • 请问<%@include file="abc.jsp"%>与<jsp:include page="abc.jsp"/>之间的差别
  • response.sendRedirect("index.jsp") 和 <jsp:forward page="index.jsp"/>的区别?
  • 想把一个jsp转到另一个jsp页面,要穿参数,中文的(jsp变量)。谁教教我?!
  • aaa.jsp有如下链接,当单击该链接时将id值传递给bbb.jsp,怎样在bbb.jsp中引用这个id值?
  • jsp+bean还是jsp+ejb还是jsp+servlet还是asp+activex好?
  • 谁能告诉我,怎么调试jsp程序呀!我在jsp中调用java,但是Tomcat这家伙只会给我报jsp文件出错。这可怎么办呀?
  • jsp中如何获得当前jsp文件所在的目录,用request.getServletPath()得到的路径含有jsp文件名,有没有办法得到目录(不含文件名)?
  • 初学jsp,一个html调用一个jsp,这个jsp调用一个javaBean,已编译成类,最后如何部署(用j2sdkee)?
  • 我要学jsp,已经下载了j2ee1.4,需要一个支持jsp引擎的WEB服务器或jsp引擎!!(急,马上给分)
  • jsp中相对路径怎么表示?例如当前目录下的jsp目录里的文件。
  • 我已经在输出前包含了<jsp:include page="2.jsp"/>,
  • 欲学JSP,请教JSP资料,最好电子版。
  • jsp中文乱码 jsp mysql 乱码的解决方法
  • jsp+JavaBean vs jsp+Servlet+JavaBean
  • JSP/html 编辑器 Bravo JSP editor
  • JSP开发入门(五)--JSP其他相关资源
  • <jsp:include page="SystemLeft.jsp?TypeId=<%= itTypeId.toString() %>" flush="true" />


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3