表联结
数据库是通过表的外键来实现表之间的联结关系的。
在hibernate之中也可以通过关系映射来实现表联结,不过使用时,数据库尽量不要使用外键hibernate的关系映射
1.单向关联:只在某一边标识对方
譬如,在Student方标识了Klass,可以通过Student操作Klass,无法通过Klass操作Student两种配置方式
<many-to-one name="roleDto" column="role_id" lazy="false">
</many-to-one>
<many-to-one name="klass" class="demo.model.hibernate.Klass" fetch="select" cascade="save-update">
<column name="class_id" />
</many-to-one>
cascade:对关联对象的级联操作。比如级联保存,级联更新和级联删除等。有4个参数
NONE:不对关联对象进行级联操作
save-update:在更新和保存的时候进行级联操作
delete:在删除本对象时删除级联对象
all:save-update+delete
cascade属性的意义就是在你操作2个关联的表时候,操作1对象中的数据时同事对关联的对象进行操作
fetch 参数指定了关联对象抓取的方式是 select 查询
lazy 是否使用懒加载,默认使用
2.双向关联:两边都要标记上对方(hibernate 自动生成的就是一个双向关联的)
即可以通过Student操作Klass
也可以通过Klass操作Student
<!--增加如下配置-->
<set name="students" inverse="true">
<key>
<column name="class_id" />
</key>
<one-to-many class="demo.model.hibernate.Student" />
</set>
举个例子,user和account 是一对多关系,如果你需要通过user找account,也需要通过account找user,这时候才需要做成双向的,双向的效率不高,所以加inverse=”true”的一方放弃维护到对方的关系(使用时尽量加上),提高效率。同样的,如果只需要通过user找account,你可以大胆的设计成user到account的单向一对多关系。一点问题也没有。根据实际的需要选择单向还是双向。
inverse=”true”表示不对双方关系进行控制,一般使用在一对多和多对多关系映射中.
在一对多中,inverse=”true”会加入到一的一方的set集合配置中(如上面),
因为一对多里,关系是由多方的外键进行控制的,一方无法控制关系,所以要这样配置.
对象的3种状态
瞬时对象(TRANSIENT OBJECT):
使用new操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收,又称游离对象。随时可能被垃圾回收器回收(在数据库中没有于之对应的记录,应为是new初始化) ,没有纳入session的管理,而执行save()方法后,就变为Persistent对象(持久性对象)
内存中一个对象, 缓存中也没有、数据库没有
持久化对象(PERSISTENT OBJECT):
持久实例是任何具有数据库标识的实例,它由持久化管理器Session统一管理,持久实例是在事务中进行操作的—-它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的INSERT、UPDATE和DELETE语句把内存中的状态同步到数据库中。在数据库有存在的对应的记录,纳入session管理。在清理缓存(脏数据检查)的时候,会和数据库同步。
内存中有、缓存中有、数据库有
离线对象(DETACHED OBJECT):
Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受hibernate管理。也可能被垃圾回收器回收掉(数据库中存在对应的记录,只是没有任何session对象引用它),曾经是Persistent状态,没有纳入session的管理内存有、缓存没有、数据库有
对这三种状态需要关注的问题是在该状态下如果进行数据库的操作会发生什么结果