Hibernate中对象的三种状态
一、Hibernate中的对象有三种状态:
1.瞬时状态(transiant):指的是没有和hibernate发生任何关系,在数据库中也没有对应的记录,一旦JVM结束,这个对象也就消失了。比如刚new出来的对象 ;
2.持久状态(persistent):指得是一个对象和hibernate发生联系,有对应的session,并且在数据库中有对应的一条记录 ;
3.游离状态(detached):当某个持久化状态的对象与session的关联被关闭后,它就变成了游离状态。游离状态的对象可能在数据库中有对应的一条记录,但是它所对应的session已经关闭了。
示例代码:
@Test public void saveRole() { Session s = SessionUtil.createSession(); Transaction tr = s.getTransaction(); //瞬时状态 RoleEntity r = new RoleEntity(); r.setRoleName("瞬时"); tr.begin(); //持久状态 s.save(r); //操作持久状态 r.setRoleName("持久"); tr.commit(); //游离状态 s.close(); }
二、一级缓存与持久化状态
1.hibernate的缓存
Hibernate中的缓存分一级缓存和二级缓存:
一级缓存就是 Session 级别的缓存,在事务范围内有效是,内置的不能被卸载。
二级缓存是 SesionFactory级别的缓存,从应用启动到应用结束有效,是可选的,默认没有二级缓存,需要手动开启。
证明一级缓存的存在:
@Test public void testOne() { Session s = SessionUtil.createSession(); UserEntity u1 = s.get(UserEntity.class, 1); UserEntity u2 = s.get(UserEntity.class, 1); UserEntity u3 = s.get(UserEntity.class, 1); System.out.println(u1 == u2);//true,说明第一次s.get是发送select语句从数据库取出记录封装成对象, 将对象放入session缓存中,后面两次只是从缓存中取出对象 System.out.println(u1 == u3);//true System.out.println(u2 == u3);//true s.close(); }
2.持久状态
持久状态,我们使用Hibernate主要是为了持久化我们的数据。
对于对象的状态,我们期望我们需要同步到数据库的数据,都被装换成持久状态。
持久化状态特点: Hibernate会自动将持久化状态对象的变化同步到数据库中。
@Test public void updateUser() { Session session = SessionUtil.createSession(); Transaction transaction = session.getTransaction(); transaction.begin(); UserEntity user = session.get(UserEntity.class, 1); //操作持久状态对象(此时不会立即同步到数据库,会先放到一级缓存,当我们提交事务的时候,hibernate会把缓存与数据库同步) user.setAge(26); //持久化对象的id不能修改,否则报错 //user.setUserId(2); //执行修改(多余的,因为在提交事务时hibernate会自动将持久化状态的实体同步到数据库中) //session.update(user); transaction.commit(); session.close(); }
Hibernate的懒加载和急加载
1.概念
急加载(FatceType.EAGER):在加载一个实体时,会立即从数据库中查询,与其关联的类也会被同时查询。
懒加载(FatchType.LAZY)是Hibernate为提高程序执行效率而提供的一种机制,简单说就是只有正真使用其属性的时候,数据库才会进行查询。
2.示例代码
//急加载 @Test public void get1() { Session s = SessionUtil.createSession(); RoleEntity r = s.get(RoleEntity.class, "40288ae670e6599b0170e659a39b0000"); System.out.println("-----------------------"); System.out.println(r.getRoleName()); s.close(); }
控制台打印:
//懒加载 @Test public void load1() { Session s = SessionUtil.createSession(); RoleEntity r = s.load(RoleEntity.class, "40288ae670e6599b0170e659a39b0000"); System.out.println("-----------------------"); System.out.println(r.getRoleName()); s.close(); }
控制台打印:
3.区别
如果使用急加载程序会在第一次运行是把数据加载到内存会消耗一段时间,往后运行查找就会很快;
懒加载会先在内存中存储查询当前的表,相关联的表则会在真正使用的时候,进行查询。