`
easyworld
  • 浏览: 113517 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Hibernate 常用保存方式区别

阅读更多

hibernate对于对象的保存提供了太多的方法,他们之间有很多不同,这里细说一下,以便区别:

  一、预备知识:

  在所有之前,说明一下,对于hibernate,它的对象有三种状态,transient、persistent、detached

  可以参考http://easyworld.iteye.com/blog/221616这篇文章

  脱管状态的实例可以通过调用save()、persist()或者saveOrUpdate()方法进行持久化。

  持久化实例可以通过调用 delete()变成脱管状态。通过get()或load()方法得到的实例都是持久化状态的。

  脱管状态的实例可以通过调用 update()、0saveOrUpdate()、lock()或者replicate()进行持久化。

  save()和persist()将会引发SQL的INSERT,delete()会引发SQLDELETE,而update()或merge()会引发SQLUPDATE.对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQLUPDATE.saveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE

  二、save 和update区别

  把这一对放在第一位的原因是因为这一对是最常用的。

  save的作用是把一个新的对象保存

  update是把一个脱管状态的对象保存

  三、update 和saveOrUpdate区别

  这个是比较好理解的,顾名思义,saveOrUpdate基本上就是合成了save和update引用hibernate reference中的一段话来解释他们的使用场合和区别。

  通常下面的场景会使用update()或saveOrUpdate():

  程序在第一个session中加载对象

  该对象被传递到表现层

  对象发生了一些改动

  该对象被返回到业务逻辑层

  程序调用第二个session的update()方法持久这些改动

  saveOrUpdate()做下面的事:

  如果对象已经在本session中持久化了,不做任何事

  如果另一个与本session关联的对象拥有相同的持久化标识(identifier),抛出一个异常

  如果对象没有持久化标识(identifier)属性,对其调用save()

  如果对象的持久标识(identifier)表明其是一个新实例化的对象,对其调用save()

  如果对象是附带版本信息的(通过或) 并且版本属性的值表明其是一个新实例化的对象,save()它。

  四、persist和save区别

  这个是最迷离的一对,表面上看起来使用哪个都行,在hibernate reference文档中也没有明确的区分他们。

  这里给出一个明确的区分。(可以跟进src看一下,虽然实现步骤类似,但是还是有细微的差别)

  1.persist把一个瞬态的实例持久化,但是并"不保证"标识符被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时间。

  2.persist"保证",当它在一个transaction外部被调用的时候并不触发一个Sql Insert,这个功能是很有用的,当我们通过继承Session/persistence context来封装一个长会话流程的时候,一个persist这样的函数是需要的。

  3.save"不保证"第2条,它要返回标识符,所以它会立即执行Sql insert,不管是不是在transaction内部。

  五、saveOrUpdateCopy,merge和update区别

  首先说明merge是用来代替saveOrUpdateCopy的,然后比较update和merge,update的作用上边说了,这里说一下merge的作用。

  如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例

  如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例,最后返回该持久实例

  用户给出的这个对象没有被关联到session上,它依旧是脱管的

  重点是最后一句:

  当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态

  但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到一个持久对象,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态。

  六、flush和update区别

  这两个的区别好理解

  update操作的是在脱管状态的对象,而flush是操作的在持久状态的对象。

  默认情况下,一个持久状态的对象是不需要update的,只要你更改了对象的值,等待hibernate flush就自动保存到数据库了。hibernate flush发生再几种情况下:

  1.调用某些查询的时候

  2.transaction commit的时候

  3.手动调用flush的时候

  七、lock和update区别

  update是把一个已经更改过的脱管状态的对象变成持久状态

  lock是把一个没有更改过的脱管状态的对象变成持久状态

  对应更改一个记录的内容,两个的操作不同:

  update的操作步骤是:

  更改脱管的对象->调用update

  lock的操作步骤是:

  调用lock把对象从脱管状态变成持久状态——>更改持久状态的对象的内容——>等待flush或者手动flush

分享到:
评论
1 楼 iamzealotwang 2008-08-12  
引用

 五、saveOrUpdateCopy,merge和update区别

  首先说明merge是用来代替saveOrUpdateCopy的,然后比较update和merge,update的作用上边说了,这里说一下merge的作用。

  如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例

  如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例,最后返回该持久实例

  用户给出的这个对象没有被关联到session上,它依旧是脱管的

  重点是最后一句:

  当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态

  但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到一个持久对象,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态。



我正好做了一个小test 应该能解释一下上面那个例子

	/**
	 *  测试Merge的第一种用法
	 *  if there is a persistent instance with the same identifier currently associated with the session, copy the state
	 *  of the given object onto the persistent instance
	 */
	public void testMergeOne(){
		Test test1 = testService.getTestDao().findById(1); //Session1: 读取ID为1的Object
		endTransaction();
		
		test1.setName("数据1"); //在Session之外改变这个值
		
		startNewTransaction(); //Session2
		Test test2 = testService.getTestDao().findById(1); //Session2: 读取ID为1的Object
		/**
		 * 将从Session1读取且在Session之外更改后的Object关联到当前Session
		 * 因为ID相同 所以覆盖test2之中的Name属性的值
		 */
		testService.getTestDao().merge(test1); 
		test1.setName("数据1已更改");
		setComplete(); //Junit中 不调用roallback
		endTransaction();
		System.out.println("Test1 Name:"+test1.getName());
		System.out.println("Test2 Name:"+test2.getName());
	}


输出结果为:

Test1 Name:数据1已更改
Test2 Name:数据1

saveOrUpdateCopy是classic里面的 已经被Merge取代了。

虽然明白怎么用Merge了,不过还是不明白在什么情况下需要用Merge。 谁能告诉我一下?

相关推荐

    hibernate常用方法集合

    `HibernateSessionFactory` 使用ThreadLocal变量`threadLocal`来存储线程绑定的Session实例。ThreadLocal是一种线程局部变量,每个线程都有自己的副本,不会互相干扰。这确保了每个线程都有独立的Session实例,避免...

    Hibernate常用包及XML

    在Java世界中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本主题将详细探讨Hibernate中的常用包及其对应的XML配置,帮助你深入理解...

    hibernate常用注解

    ### Hibernate常用注解详解 #### 一、JPA与Hibernate注解基础 JPA(Java Persistence API)是一种标准规范,用于实现对象关系映射(ORM),允许开发人员使用注解或XML来描述实体对象与数据库表之间的映射关系。...

    Hibernate常用的资料以及面试题

    本资料集主要涵盖了Hibernate的基础知识、常用操作以及面试常见问题,旨在帮助开发者深入理解Hibernate并提升面试技能。 1. **Hibernate简介** Hibernate是一个开源的ORM(Object-Relational Mapping)框架,它...

    Hibernate常用的jar包和两个配置文件

    一、Hibernate常用jar包 1. **hibernate-core.jar**:这是Hibernate的核心库,包含了所有必要的API和实现,包括Entity管理、Session接口、Query语言等。 2. **hibernate-entitymanager.jar**:提供了JPA(Java ...

    spring hibernate执行存储过程的例子

    Spring和Hibernate是Java开发中常用的两个框架,它们提供了对存储过程的支持。本文将深入探讨如何在Spring和Hibernate中执行存储过程,并基于描述中的例子进行解析。 首先,让我们了解Spring如何执行存储过程。...

    hibernate常用包(包含数据库)

    标题中的“hibernate常用包(包含数据库)”指的是Hibernate框架的基础组件,这些组件是进行JavaWeb开发中数据持久化操作的关键。Hibernate是一个强大的对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间...

    hibernate 3.5.5 常用jar包

    在这个“hibernate 3.5.5 常用jar包”中,包含了运行和开发基于Hibernate 3.5.5应用所需的核心库。以下是关于Hibernate 3.5.5及其相关jar包的关键知识点: 1. **对象关系映射(ORM)**:ORM是将数据库中的表映射为...

    常用 Hibernate 映射配置说明.doc

    ### 常用Hibernate映射配置详解 #### 1. hibernate-mapping节点解析 `hibernate-mapping`节点是Hibernate映射文件中的顶级节点,用于定义一系列配置选项,控制整个映射文件的行为和映射规则。这些配置包括数据库...

    hibernate3.5.5常用jar包搜集

    Hibernate 是一个开源的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式来操作数据库,极大地简化了Java应用中的数据访问层。这个压缩包“hibernate3.5.5常用jar包搜集”包含了用于使用Hibernate 3.5.5...

    hibernate常用lib

    这个压缩包文件"hibernate常用lib"包含了开发Hibernate应用所需的常用库文件,总计16个。这些库文件通常包括Hibernate的核心库、数据库驱动、依赖的第三方库等,是构建基于Hibernate的应用程序的基础。 在Hibernate...

    hibernate工程常用jar包

    在Java开发领域,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本资源“hibernate工程常用jar包”包含的是Hibernate 3.0版本及其相关配置...

    spring+springmvc+hibernate常用jar

    标题中的"spring+springmvc+hibernate常用jar"指的是在Java Web开发中,整合Spring框架、Spring MVC和Hibernate框架时所需的常用库文件。这些jar文件是构建基于这三大框架的应用程序的基础,允许开发者实现模型-视图...

    C#Hibernate数据库海量读写快速存储

    本话题主要探讨了如何利用C#编程语言以及Hibernate ORM框架,在SQL Server数据库上实现快速的存储和检索。以下是对这些关键知识点的详细阐述: 一、C#编程语言: C#是一种由微软开发的面向对象的编程语言,广泛应用...

    Hibernate的各种保存方式的区别详解

    Hibernate保存方式的区别详解 Hibernate提供了多种保存方式,包括save()、persist()、update()、saveOrUpdate()等,了解这些方法的区别非常重要,以便正确使用它们。本文将对Hibernate的各种保存方式进行详细的比较...

    hibernate5常用的jar包集合(连接mysql)

    在Hibernate项目中,JUnit可以帮助开发者验证ORM逻辑是否按预期工作,例如测试实体的保存、更新、查询等操作。 5. **其他依赖**:Hibernate 5可能还需要其他一些库,如slf4j-api.jar和slf4j-log4j12.jar,它们提供...

    Hibernate知识点总结

    #### 四、Hibernate常用接口和类 - **Configuration**:负责管理Hibernate的配置信息,包括数据库连接信息、持久化类与数据表的映射关系等。 - **ServiceRegistry**:用于管理Hibernate的服务和配置,确保服务的...

    hibernate主键生成策略

    每个数据库都有自己的序列生成方式,Hibernate通过这个策略与之配合。 7. **uuid.hex**和**uuid.string**策略: 这两种策略生成基于UUID的128位二进制或16进制字符串,确保全局唯一,适用于分布式系统。 8. **...

    Hibernate常用总结

    JobsDemo where jobDesc like :desc"); query.setParameter("desc", ...同时,Hibernate 提供了丰富的查询方式,如 HQL 和 Criteria API,以及事务管理功能,使得开发者能够更加专注于业务逻辑而非底层数据访问细节。

    hibernate的第一个例子

    例如,创建一个新的User对象,保存到数据库,然后查询验证其是否成功存储。 5. **配置文件(Hibernate.cfg.xml)**:每个Hibernate应用都需要一个配置文件,其中包含了数据库连接信息、方言、缓存设置等。在例子中...

Global site tag (gtag.js) - Google Analytics