一、实体对象的生命周期
实体对象的生命周期在Hibernate应用中是一个很关键的概念,正确的理解实体对象的生命周期将对我们应用Hibernate做持久层设计起到很大的作用。而所谓的实体对象的生命周期就是指实体对象由产生到被GC回收的一段过程。在这过程中我们需要理解的就是实体对象生命周期中的三种状态。
1、 自由状态(Transient)
所谓的Transient状态,即实体对象在内存中自由存在,与数据库中的记录无关,通常是我们的J2EE中VO,并没有被纳入Hibernate的实体管理容器。
User user = new User();
User.setName(“admin”); //此时的user对象处于Transient(自由状态)并没有被Hibernate框架所管理
2、 持久状态(Persistent)
何谓 Persistent?即实体对象已经处于被Hibernate实体管理容器所管理的状态。这种状态下这个实体对象的引用将被纳入Hibernate实体管理容器所管理。处于Persistent状态的实体对象,对它的变更也将被固化到数据库中,在J2EE中通常指的是一个PO。处于Persistent状态的实体可以简单的理解为:如果一个实体对象与session发生了关联,并且处于session的有效期内,那么这个实体对象就处于Persistent状态。
Transaction tx = session.beginTransaction();
Session.save(user); //此时的user对象已经处于Persistent(持久状态)它被Hibernate纳入实体管理容器
Tx.commit();
Transaction tx2 = session.beginTransaction();
User.setName(“modity name”); 在这个事务中我们并没有显示的调用save()方法但是由于Persistent状态的对象将会自动的固化到数据库中,因此此时正处在Persistent状态的user对象的变化也将自动被同步到数据库中
Tx2.commit();
3、 游离状态(Detached)
处于Persistent状态的实体对象,其对应的session关闭以后,那么这个实体就处于Detached状态。我们可以认为session对象就是一个Persistent的宿主,一旦这个宿主失效,那么这个实体就处于Detached状态。
Session.close(); //与user对象关联的session被关闭,因此此时的user对象进入Detached(游离状态)
Session session2 = SessionFactory.getSession(); //此时正处于Detached状态的user对象由于再次借助与session2被纳入到Hibernate的实体管理容器所以此时的user对象恢复到Persistent状态
Transaction tx3 = session2.beginTransaction();
Session2.update(user);
Tx3.commit();
既然Transient状态的实体与Detached状态的实体都与Hibernate的实体管理容器没有关系,那他们到底存在哪些差异?差异就在于处于Transient状态的只有一个Name的属性,此时的user对象所包含的数据信息仅限于此,他与数据库中的记录没有任何瓜葛。但是处于Detached状态的实体已经不止包含Name这个属性,还被赋予了主键也就是通常POJO里的id属性,由于id是主键,他可以确定数据库表中的一条唯一的记录,那么自然的处于Detached状态的实体就能与数据库表中拥有相同id的记录相关联。这就是他们之间所存在的差异,简而言之,Transient状态的实体缺乏与数据库表记录之间的联系,而Detached状态的恰恰相反,只不过是脱离了session这个数据库操作平台而已。
三、多对一关系映射
1、 实体对象:student(学生)、clazz(班级),关系对象:t_student,t_clazz两个表。Student对应clazz实体对象是多对一的关系,多个学生属于一个班级。在student关系映射中加上多对一个的关系:
<many-to-one name=”clazz” column=”clazz_id” not-null=”true”/>
2、 实体对象:student(学生)、clazz(班级),关系对象:t_student,t_clazz,t_studentclazz三个表,t_studentclazz表存储学生和班级的关联关系。
在student关系映射中加上多对一个的关系:
<join table=”t_studentclazz” optional=”true”>
<key column=”student_id” unique=”true”/>
<many-to-one name=”clazz” column=”clazz_id” not-null=”true”/>
</join>
四、一对一关系映射(假设一个班级只有一个学生,不过分)
1、 基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。
<many-to-one name=”clazz” column=”clazz_id” unique=”true” not-null=”true”/>
2、 基于主键关联的单向一对一关联通常使用一个特定的id生成器。
<id name=”id” column=”clazz_id”>
<generator class=”foreign”>
<param name=”property”>clazz</param>
</generator>
<one-to-one name=”clazz” constrained=”true”/>
</id>
3、 基于连接表的单向一对一关联
<join table=”t_studentclazz” optional=”true”>
<key column=”student_id” unique=”true”/>
<many-to-one name=”clazz” column=”clazz_id” not-null=”true” unique=”true”/>
</join>