Hibernate学习笔记(四)【操纵对象篇】
A Session的缓存作用
1.1 减少访问数据库的频率 1.2 当缓存中的持久化对象间存在循环关联关系时,保证不死循环 1.3 保证数据库中相关记录与缓存中的相应对象保持同步
B 脏检查及刷新缓存的机制
1.1刷新缓存Flush时,执行SQL顺序
a) 调用session.save()方法的先后顺序,实体执行insert语句 b) 实体执行update语句 c) 集合进行delete语句 d) 集合进行删除、更新或者插入sql语句 e) 集合进行insert语句 f) 按照调用session.delete()方法的先后顺序,执行实体删除delete语句
1.2刷新缓存时间点
a) Transaction的commit()方法 b) 执行查询操作时,缓存中持久化对象属性已经变化,实施同步 c) 调用Session的flush()方法
1.3session.setFlushMode(FlushMode.COMMIT)
各种查询方法 | commit() | flush() | |
FlusMode.AUTO默认 | 清理 | 清理 | 清理 |
FlushMode.COMMIT | 不清理 | 清理 | 清理 |
FlushMode.NEVER | 不清理 | 不清理 | 清理 |
C Java对象在Hibernate持久化层的状态
临时状态(transient): 刚刚new,未被持久化,不存于Session缓存 持久化状态(persistent): 已经被持久化,并且加入Session缓存 删除状态(removed): 不在处理Session缓存中并且Session计划从数据库删除 游离状态(detached): 持久化转化而来,不存于Session缓存,数据库有对应记录
Monkey对象 生命周期 状态 tx = session.beginTransaction(); 开始生命周期 临时状态 Monkey m1 = new Monkey(“Tom”); session.save(m1); 处于生命周期 转持久态 Long id = m1.getId(); 处于生命周期 处于持久态 m1=null; //session缓存会引用它 Monkey m2 = (Monkey) session.get (Monkey.class, id); tx.commit(); session.close(); 处于生命周期 转游离态 System.out.println(m2.getName()); 处于生命周期 处于游离态 m2=null; 结束生命周期 结束生命周期
持久化变游离态方法:
a. Session.close() session缓存被清空 b. Session.evict() 从缓存中清除一个持久化对象 c. Session.clear() 清除缓存中所有持久化对象
D Session接口详细用法
save() 当清理缓存时才执行SQL save() 返回对象的标识符,而save方法可以保存任何状态的对象。 persist()方法无返回值。此外,persist方法只能保存临时态和持久态的对象
get() 方法始终返回对象的实例,查找指定OID不存在,返回null; load() 方法除非在持久化上下文中已经存在一个该标识符定位的对象,不然总是先返回对象的代理,指定OID不存在,抛出ObjectNotFoundException 默认所有持久化类都采用延迟检索策略,及映射<class>元素lazy属性默认”ture” <class name=”mypack.Monkey” table=”MONKEYS” lazy=”true”> lazy属性为”false”,load方法才采用立即检索策略 get() 忽略该属性,总是采用立即检索策略 lazy属性为” ture”,load方法采用延迟检索策略,get()采用立即检索 get() 方法访问各属性 load() 方法为了删除,或者建立与别的对象的关系
update() 把游离对象转变为持久对象,计划执行update语句,清缓存时只执行一次 <classname=”mypack.Monkey” table=”MONKEYS” select-before-update=”true”> 变化时,才执行update,所以如果不经常变,就ture,默认为false,经常变时默认 saveOrUpdate() 判断游离就UPDATE,不是就SAVE OID为null,基础类型为OID的话就为初始值如long为id,就是0,或者版本控制version为null,有unsaved-value属性值就以它为准或null,这时就save否则update,如果无该id就抛插入异常 session.merge()关联游离态则复制到同UID持久态对象中,然后将游离态内容更新到数据库中,计划执行update session.merge关联游离态若无同UID的持久态对象,则根据该UID加载持久态对象,然后复制到该持久态,计划执行update,若数据库无该uid对象则创建新对象,复制进去,调用save()转持久态 session.merge关联临时态则创建对象,复制到该对象,最后调save()转持久态对象 session.updat()关联游离态转为持久态,计划执行update,但本来已存该持久态,则抛异常 session.delete()删除游离态对象,先是游离对象被session关联,变持久态删除 删除持久态,计划执行delete语句(清理缓存时,一次一个,不建议再使用)
E 级联操作对象图
cascade属性
描述 none 在保存更新时,忽略其他关联对象,他是cascade默认属性 save-update 当通过Session的save(),update()以及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象 delete 当通过session的delete()方法删除当前对象时,及联删除所有对象 lock 把游离对象加入缓存当中,关联对象也加入 evict 把持久化对象从缓存中移除,关联对象也移除 refresh 刷新当前缓存中对象,级联对象也会刷新 all 包含save-update、 delete、 evict、lock及refresh的行为 delete-orphan 删除所有和当前对象解除关联关系的对象 all-delete-orphan 包含all和delete-orphan
G 批量处理数据
1. 通过Session来进行批量操作
a) 配置JDBC单次批量处理数目10~50:hibernate.jdbc.batch_size=20 b) 采用”identity” c) 批量操作建议关闭Hibernate二级缓存(SessionFactory应用范围) hibernate.cache.use_second_level_cache=false 进程/集群 session.flush(); session.clear(); d) 更新的话用Query q = session.createQuery(selectHQL ); ScorllableResults sr =Query.scroll(ScrollMode.FORWARD_ONLY) sr.next() sr.get(0)
2.通过StatelessSession来进行批量操作
a) StatelessSession session =SessionFactory.openStatelessSession(); b) 无缓存,加载保存更新数据后都为游离态 c) 不与二级缓存交互 d) 立即执行SQL e) 不自动进行脏检查,变化内存对象属性后需显示调用update()更新 f) 不会对关联对象进行任何级联操作 g) 加载两次同UID对象,是具有不同内存地址的对象
3.通过HQL来进行批量操作
a) 批量更新session.createQuery(updateHQL ).executeUpdate() b) 批量删除session.createQuery(deleteHQL ).executeUpdate() 例子:String deleteHQL = “delete Monkey m where m.name = :oldName” session.createQuery(deleteHQL).setString(“oldName”,”Tom”) .executeUpdate() c) 批量插入session.createQuery(insertHQL ).executeUpdate() 只支持insert into…select… 不支持insert into …values…
相关推荐
鲁氏汤包王 2020-06-08
solarspot 2020-07-28
houmenghu 2020-11-17
我心似明月 2020-11-09
oraclemch 2020-11-06
ltd00 2020-09-12
康慧欣 2020-09-10
waveclouds 2020-09-04
蓝色深海 2020-09-15
jincheng 2020-09-01
思君夜未眠 2020-08-25
取个好名字真难 2020-08-06
歆萌 2020-08-03
阳光之吻 2020-08-03
婷婷小屋 2020-07-28
MLXY 2020-07-26
dxbjfu0 2020-07-26
songbinxu 2020-07-19