纸上得来终觉浅
下面根据上篇文章“Hibernate基本示例”的代码进行演示:
1.Session一级缓存
1) session缓存的概念,数据库中的数据在被拿到session中时,是以java集合的形式保存,这些java集合就构成了session缓存; 之所以有缓存是为了减少访问数据库的频率;
User user2 = (User)session.get(User.class, 1L);
System.out.println("HibernateTest.test():"+user2);
User user3 = (User)session.get(User.class, 1L);
System.out.println("HibernateTest.test():"+user3);
这个时候,只会访问一次数据库,第二次发送请求的时候,直接从缓存中取,而不是再次访问数据库。
2)在session关闭之后重新打开或者session进行clear操作后,会有第二次请求:
User user2 = (User)session.get(User.class, 1L);
System.out.println("HibernateTest.test():"+user2);
/*重新开启session*/
transaction.commit();
session.close();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
/*清理session缓存*/
// session.clear();
User user3 = (User)session.get(User.class, 1L);
System.out.println("HibernateTest.test():"+user3);
这个时候会看到两次select语句
3)flush和refresh对缓存的影响,先看一张图:
首先flush操作是根据session中数据的变化来对数据库操作,不会影响session缓存本身,所以即使两次查询之间flush也只会有一次select语句;而refresh指的根据数据库当前记录重新更新session缓存,这个时候会又一次进行select操作,所以最后会看到两个select语句,只是这个select是由于refrsh引起,不是第二次查询对象引起。如下:
User user2 = (User)session.get(User.class, 1L);
System.out.println("HibernateTest.test():"+user2);
/*对数据库进行更改*/
session.flush();
/*根据数据库重新查询user2*/
// session.refresh(user2);
User user3 = (User)session.get(User.class, 1L);
System.out.println("HibernateTest.test():"+user3);
2.sava和persist方法区别:
都是进行保存操作,只是在保存之前如果对象设置了ID,对sava来说直接忽略,对persist来说会报错。
user.setName("majintao");
user.setPhoneNum("18788837117");
user.setId(10L);
session.save(user);
// session.persist(user);
System.out.println("HibernateTest.test()User"+user);
3.get和load方法区别:
1)get立即加载;load延迟加载(懒加载),在用到对象的时候再进行加载;
2)数据库中没有相关记录,get返回null,load返回 org.hibernate.ObjectNotFoundException;
3)如果在加载之后关闭session,使用对象时,get因为是立即加载可以使用,load返回org.hibernate.LazyInitializationException: could not initialize proxy - no Session
4.update方法:
1)更新一个持久化的对象,不用显示的调用update,因为在事务的commit中已经有了flush的操作,进行flush的时候会根据session中的数据对数据库进行更新:
User user2 = (User)session.load(User.class, 1L);
user2.setName("zhangzhilin");
System.out.println("HibernateTest.test()"+user2);
2)更新一个游离的对象需要显示调用update,因为游离对象,这个时候session已经关闭;再次开启的时候session没有这个对象的缓存,修改数据的时候,session缓存更不会随着更新,那么在flush的时候数据库记录也不会更改,所以需要显示调用update:
User user2 = (User)session.get(User.class, 1L);
transaction.commit();
session.close();
session=sessionFactory.openSession();
transaction=session.beginTransaction();
user2.setName("zhougongjin");
session.update(user2);
System.out.println("HibernateTest.test()"+user2);
注:
游离对象更新,无论对象有没有更改,都会发送update语句(持久化对象更新时,只在对象发生变化的时候发送update语句)
update方法关联一个游离对象,如果session缓存中已经存在相同OID的持久化对象,会抛出异常
update方法关联一个游离对象,数据库中不存在相应的记录,也会抛出异常
5 saveOrUpdate方法:
该方法包含了save和update方法:OID为null执行sava,OID不为null,执行updare。
6.delete方法
删除一个对象后,该对象的id仍然存在,可以通过hibernate.use_identifier_rollback属性设置为true,delete之后对象的id会变为null,变成临时对象。
7.evict方法
把指定的对象从session缓存中移除。
User user2 = (User)session.get(User.class, 1L);
session.evict(user2);
User user3 = (User)session.get(User.class, 1L);
会看到两个select
以上就是Session的基本方法。