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.3 session.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…