1. one端set标签的设置
<set name="acts" cascade="all" inverse="true"><!-- 让one端(user)将关系的维护方交给另一端:many端(Account) -->
<key column="fid"></key>
<one-to-many class="Account"/><!-- 指定集合中存放的是Account类 -->
</set>
注:inverse="true"就是在设置如果在内存中的修改或添加了这个集合中的某一个或某几个对象他不会将全部集合的信息同步到数据库,而是只将集合中被修改的对象重新同步到数据库。
2. many端
<many-to-one name="user" column="fid" cascade="save"><!-- 设置级联操作 -->
</many-to-one>
二.状态
1. 持久对象的状态-->PO外在的状态 (OOAD中 对象的状态-->PO内在的状态)
Transient 暂时状态: po 和Session无关,数据库中也无该记录
Persistent 持久状态: po 和Session有关,数据库中有该记录
Detached 游离/脱管态:po和Session无关,数据库中有该记录
注:和Session关系,即Session中有该对象的副本和该对象的引用
持久化对象: 即就是在数据库中存有其相对应数据的对象,并且在内存中也有这个对象,内部状态和外部状态同步, 这个对象在Session的管理范围内,也就是调用Session.save()方法同步到数据库的对象。
临时对象: 即在内存中刚刚创建(new)的对象,还没有同步到数据库,或者是调用Session.delete(),数据库中信息被删除了的对象。
游离对象: 也就是在数据库中有和该对象向对应的纪录,并且在内存中的也存在该对象,但是不在Session的管理范围之内,如在Session关闭之后,就成了游离对象,就不会在将其改变同步到数据库中.
内在状态-->外在化? 是-->持久态 --否-->暂态
(类属性) (表记录) --是-->Session同步?否-->游离态
2. 状态转换: _|_-->close():关闭Session/clear()清空缓存内对象/evict()清除某个持久对象
save() / saveOrUpdate() close()/clear()/evict()
Transient--------------------->Persistent----------------------->Detached
(临时态)<---------------------(持久态)<----------------------- (游离态)
delete() update()/saveOrUpdate()/lock()
三. 级联操作cascade
cascade属性是设置级联操作的也就是在操作一端的数据如果影响到多端数据时会进行级联操作.
1. none: 就是只对本对象进行操作,不使用级联操作,默认级联是none。
2. save-update: 也就是只有对象保存操作(持久化操作)或者是持久化对象的更新操作,才会级联操作关联对象(子对象),one2many关系中多的那一方会使用;
3. delete: 对持久化对象的删除操作时会进行级联操作关联对象(子对象)。
4. all: 对持久化对象的所有操作都会级联操作关联对象(子对象)。
5. all-delete-orphan: 在多端进行删除操作时,会在多端表中留下null空纪录,设置了级联操作为delete之会将表中表示关联的外键id置成null,不会将这条纪录也删除掉,而把级联设置成delete-orphan就不会留有空纪录,而是级联的把相关纪录删除掉。(级别最深)
cascade="save-update,delete-orphan"
四. 批量更新(Batch update)
1. session.flush()和session.clear()联合使用
2. batch-size: 这个属性写在set标签中,代表批量加载,也就是在加载一端的集合属性时会一次加载指定的数量的对象,而不是默认的一个一个的加载,会提高效率,批量加载只能用于延迟加载和立即加载策略,也就是(lazy="true"或者lazy="false")。
注: lazy="true" 延迟加载,所谓的延迟加载,就是对一端的集合属性的加载策略,就是在不使用到集合中的对象的数据就不会真正的加载集合中的对象数据,而是家在一个代理对象就相当于的一个空的容器。这也就是会出现LazyInitializationException异常,也就是没有初始化这个代理的集合对象,在事先查询到了集合中的对象就会初始化这个对象,如果Session没有关闭就会在查询加载集合中的对象信息,如果提前关闭了Session,当使用集合中的对象信息时就会有这个异常。
五. Hibernate控制的事务(ACID,atomicity consistency isolation durability)事务保证原子操作的不可分,也就是操作的同时成功或同时失败。
Transaction tran=session.beginTranaction();//....事务操作
tran.commit();
tran.rollback();
以上是事务对象的方法,来实现对事务的支持。
六、hibernate的事务隔离级别
hibernate的事务隔离级别和JDBC中大致相同。
设置时要在hibernate.cfg.xml配置
<property name="hibernate.connection.isolation">4</property>
1,读未提交的数据(Read uncommitted isolation)
2,读已提交的数据(Read committed isolation)
4,可重复读级别(Repeatable read isolation)
8,可串行化级别(Serializable isolation)
七、hibernate的锁(悲观锁,乐观锁)
1. 悲观锁: 是由数据库本身所实现的,会对数据库中的数据进行锁定,也就是锁行,在同一时间内只能有一个读写数据操作。
LockMode.UPGRADE,修改锁,在get()方法中加上这个设置作为第三个参数。
LockMode.NONE 无锁机制
LockMode.READ 读取锁(JDBC中的for update)
LockMode.WRITE 写入锁,不能在程序中直接使用
例如:tran = s.beginTransaction();
user = (User)s.get(User.class , userid , LockMode.UPGRADE);
user.setName("new name");
tran.commit();
还可以使用Session.lock() Query.setLockMode() Criteria.setLockMode()方法来设置锁
2. 乐观锁: 也就是通过对记录加上某些信息来解决并发访问的问题。
解决冲突的手段: 加上版本versionNo
if(read_versionNo=versionNo) write versionNo++ else do it again
<version name="version"/>必须紧跟在<id>之后persist就只是将级联对象也持久化到数据库。
分享到:
相关推荐
在提供的文件"hibernate_day03"中,可能包含相关的代码示例和更深入的解释,通过阅读和实践这些内容,你可以更好地掌握Hibernate的抓取策略,特别是对于"many-to-one"关系的应用。记住,理论知识固然重要,但实践...
3. 多对多(Many-to-Many):多个实体可以对应多个其他实体。如,学生可以选择多门课程,课程也可以被多个学生选修。这通常需要一个中间表来存储关系,通过@ManyToMany注解配置。 最后,我们来看MyBatis的一对一...
在项目实践中,为了更好地理解这个例子,你可以打开`day56_01hibernate one2many`目录,查看具体代码,包括实体类、映射文件、DAO层、Service层以及相关的测试类。通过分析这些代码,你将能更好地掌握Hibernate一对...