1.Session 接口是Hibernate向应用程序提供的操作数据库的主要接口,提供基本保存,更新,删除和加载Java对象方法。
2.站在持久化角度,Hibernate把对象分为4中状态:
持久状态:OID不为空,在Session缓存中,在同一个Session实例的缓存中,数据表中每条记录只能对应唯一持久化对象。
临时状态:OID为null,不在Session缓存中,在数据库中没有对应记录。
游离状态:OID不为空,不在Session缓存中,游离态由持久化转换来,数据库中可能有与其对应对象。
删除状态:OID为null,不在Session缓存中,曾经被Session监管过。数据库中没有。
3.Session的一级缓存
第一次查询News对象的时候,会把对象分配给news和session缓存,而第二次查询的时候,session缓存中存在。
@Test
public void testSessionCache(){
News news = (News) session.get(News.class, 1);
System.out.println(news);
News news2 = (News) session.get(News.class, 1);
System.out.println(news2);
}
4.Session的Flush方法
首先获取News对象,然后修改字段。此时控制台会发出两条语句,因为在一个事务中,先发送selec,后感知到对象变化发送update。实际上在commit之前调用了flush()方法。
这个动作是为了保证session缓存和数据库数据保持一致。就是缓存修改了,需要更新到数据库中。
也可以显式调用session.flush();
@Test
public void testSessionFlush(){
News news = (News) session.get(News.class, 1);
news.setAuthor("Oracle");
}
@Test
public void testSessionFlush2(){
News news = new News("Java", "AAAA", new Date());
session.save(news);
}
但是,表主键使用hibernate产生id的话,则会在最后commit执行insert操作。
5.reflesh()方法
该方法会强制查数据库记录,发送select语句,保证数据最新。注意:受到数据库事务隔离级别影响,reflesh可能失效。MySql默认级别为可重复读,需要修改隔离级别
在hibernate.cfg.xml中设置级别:
<!-- 设置 Hibernate 的事务隔离级别 2为读已提交-->
<property name="connection.isolation">2</property>
@Test
public void testRefresh(){
News news = (News) session.get(News.class, 4);
System.out.println(news);
session.refresh(news); //如果在数据库中手动更改该数据,不refresh的话,则取出来的缓存不是数据库最新的。
System.out.println(news);
}
6.清理缓存
使用clear()方法会清理session中的缓存,所以下面的查询会发送两条select语句。
@Test
public void testClear(){
News news1 = (News) session.get(News.class, 5);
session.clear();
News news2 = (News) session.get(News.class, 5);
}