hibernate中的对象可以划分为三种,分别是瞬时对象,持久对象和脱管对象,三种状态的详细介绍如下。
1.瞬时对象
由new操作符创建,且尚未与Session 关联的对象被认定为瞬时(Transient)的,不和数据库的数据有任何关联关系。瞬时(Transient)对象没有被持久化到数据库中,也不会被赋予持久化标识(identifier)。
如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁。 由于此对象没有纳入Session的管理,那么此时该对象的任何变化都不会发出SQL语句。
但是可以用Session的持久方法(save(),saveOrUpdate()等)进行持久化操作时才会转变为持久对象并拥有和数据库记录相同的id标识。
2.持久对象
持久(Persistent)对象在数据库中有对应的记录,并拥有一个持久化标识(identifier)。 持久对象可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。 它有持久化管理器Session统一管理,持久对象是在事务中进行操作的——Transaction实例执行commit()之后,与数据库进行同步。当事务提交时,通过执行SQL的INSERT、UPDATE和DELETE语句把内存中的状态同步到数据库中。
持久化对象任何变化都会自动地发出SQL语句,也就是说该对象和数据库是实时联动(同步的)。
3.脱管对象与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的。托管表示这个对象不能再与数据库保持同步,它们不再受Session管理。
对脱管(Detached)对象的引用依然有效,对象可继续被修改。脱管(Detached)对象如果重新关联到某个新的Session上, 会再次转变为持久(Persistent)的(在Detached期间的改动将被持久化到数据库)。
对象识别
对数据库而言,其识别一条记录唯一性的方式是根据主键值,如果手上有两条记录,它们拥有同样的主键值,则它们在数据库中代表同一个字段的记录。对Java而言,要识别两个对象是否为同一个对象有两种方式
(1)内存地址识别(“= =”号识别)
(2)根据equals()、hasCode()中的定义
其中重写equals()和hasCode()与Java中的类似,所以顺带复习下:
1. equals与==的区别。
== 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。
2. Hashcode的作用。
hashCode()方法是为任何一个对象生成一个哈希码,相同(逻辑上认为)的对象应该生成相同的哈希码,Java内置的求出的哈希码是基于存储地址的一个映射关系,保证了对象的哈希码的一一对应关系。散列存储,即是根据一个关键字找到对应的对象,存在对应的哈希表里,
重写equals()方法就必须重写hashCode()方法主要是针对HashSet和Map集合类型 。集合框架只能存入对象(对象的引用(基本类型数据:自动装箱))。
在向HashSet集合中存入一个元素时,HashSet会调用该对象(存入对象)的hashCode()方法来得到该对象的hashCode()值,然后根据该hashCode值决定该对象在HashSet中存储的位置。简单的说:HashSet集合判断两个元素相等的标准是:两个对象通过equals()方法比较相等,并且两个对象的HashCode()方法返回值也相等。如果两个元素通过equals()方法比较返回true,但是它们的hashCode()方法返回值不同,HashSet会把它们存储在不同的位置,依然可以添加成功。同样:在Map集合中,例如其子类Hashtable(jdk1.0错误的命名规范),HashMap,存储的数据是key,value对,key,value都是对象,被封装在Map.Entry,即:每个集合元素都是Map.Entry对象。在Map集合中,判断key相等标准也是:两个key通过equals()方法比较返回true,两个key的hashCode的值也必须相等。判断valude是否相等equal()相等即可。
稍微提一句:
(1)两个对象,用==比较比较的是地址,需采用equals方法(可根据需求重写)比较。
(2)重写equals()方法就重写hashCode()方法。
(3)一般相等的对象都规定有相同的hashCode。
集合类都重写了toString方法。String类重写了equal和hashCode方法,比较的是值。