1. Session 缓存: 1) . 在 Session 接口的实现中包含一系列的 Java 集合 , 这些 Java 集合构成了 Session 缓存 . 它 用于存放 Session 关联的对象 ( Session 关联对象的方式有很多种。 例如:session.get ( Class , OID ) 、 session.update () 、 session
1. Session 缓存:
1) . 在 Session 接口的实现中包含一系列的 Java 集合
, 这些 Java 集合构成了 Session 缓存 .
它
用于存放 Session 关联的对象( Session 关联对象的方式有很多种。
例如:session.get
(Class
, OID
)、 session.update
()、 session.save
() ...)。
只要 Session 实例没有结束生命周期
, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期。
Session 缓存可减少 Hibernate 应用程序访问数据库的频率。
2) . 操作 Session 缓存的方法(了解一下吧)。
①. 若调用 session.get
() 从数据库中加载一个对象,则该对象会被纳入到 Session 缓存中。
News news
= (News
) session.get
(News.class
, 1
);
//会向数据库发送 SQL 吗 ? 不会发送 SQL 语句
, 而是从 Session 缓存获取对象的引用(快照)
News news2
= (News
) session.get
(News.class
, 1
);
②. Session 的 clear
() 方法可以清空 Session 的缓存
News news
= (News
) session.get
(News.class
, 1
);
//清理
session 缓存
session.clear
();
//会向数据库发送 SQL 吗 ? 会 ! 因为 Session 缓存被清空了 !
News news2
= (News
) session.get
(News.class
, 1
);
③. Session 的
flush() 方法:
清理缓存
- 强制使数据库记录和 Session 缓存中对象状态保持一致,可能会发送 SQL 语句
(若数据库记录和 Session 中对象状态不一致,则发送 SQL,否则不发送 SQL)
I. 默认情况下,提交事务时,会先清理缓存,然后再提交事务
II. 若主键生成方式使用的是数据库底层的自增长方式,会在执行 Session 的 save
() 方法时,就清理缓存,执行 INSERT 语句,而不是等到提交事务时。 Hibernate 要求和 Session 关联的对象必须有和数据表记录对应的 OID,这就意味着执行 save
() 方法后,必须有 OID ,而底层自增长的方式生成主键,必须先执行 INSERT 才能获取主键值
//若使用 MySQL 底层自增的方式生成主键, save
() 方法即会引起发送 INSERT 语句
session.save
(news
);
System.out.println
(news.getId
());
III. 使用 HQL(Hibernate
Query Language )查询记录时,不经过 Session 缓存!直接查询数据库,且要求查询的结果是最新的!
所以,在进行 HQL 查询之前需要先清理缓存
session.save
(news
);
//会导致清理缓存
News news2
= (News
) session.createQuery
("FROM
News n WHERE n.id = ?"
)
.setInteger
(0
, news.getId
()).uniqueResult
();
IV. commit
() 和 flush() 方法的区别:
flush 执行一系列 sql 语句,但不提交事务;
commit 方法先调用flush
() 方法,然后提交事务 . 意味着提交事务对数据库的操作永久保存下来。
④.
refresh
() 方法:
强制使 Session 缓存中的对象的状态和数据库记录保持一致。所以会强制发送一条 SELECT 语句。
注意,因为 MySQL 的默认的隔离级别为 READ
REPTABLE 。所以需要设置事务的隔离级别才能看到实验的效果
<!-- 设置 Hibernate 的事务的隔离级别, 设置为读已提交 -->
<property
name
="connection.isolation"
>2
property
>