Hibernate三种状态和Session常用的方法

来源:互联网 发布:mac book pro 201515.4 编辑:程序博客网 时间:2024/06/05 14:28

Hibernate三种状态和Session常用的方法

原创 2015年12月20日 00:09:51

       我们知道Hibernate的核心就是对数据库的操作,里面的核心接口就是org.hibernate.Session接口。要想对数据库操作我们就要理清楚对象在整个操作中的所属的状态(Transient,Persistent,Detached)。就像马士兵老师在视频中所说的,我们并不必死抠这些字眼,我们通过自己编写测试类就可以他们之间不同的区别。

       其实三种状态各自的不必总结那么多,只是一个重要的地方就是Transient状态里面的对象是没有id的。

      

      session中常用的方法是save(),update(),saveOrUpdate(),get(),load(),delete(),clear(),flush()这些

      其中大学期间我其实对get和load方法都不是太熟悉,死记硬背才在考试中答题,现在想起完全没有这个必要。我们可以根据配置好的hibernate环境来进行junit测试。

首先我们进行get()方法进行测试。

    这里我们首先建立一个实体类,StudentEntity.java 和数据库中student所对应

[java] view plain copy
  1. package com.cwnu.entities;  
  2.   
  3. import javax.persistence.*;  
  4. import java.io.Serializable;  
  5.   
  6. /** 
  7.  * Created by yangy on 2015/12/19. 
  8.  */  
  9. @Table(name = "student")  
  10. @Entity  
  11. public class StudentEntity implements Serializable{  
  12.     private int id;  
  13.     private String name;  
  14.       
  15.     @Id  
  16.     @Column(name = "id")  
  17.     @GeneratedValue(strategy = GenerationType.AUTO)  
  18.     private int getId() {  
  19.         return id;  
  20.     }  
  21.   
  22.     public void setId(int id) {  
  23.         this.id = id;  
  24.     }  
  25.   
  26.     @Column(name = "name")  
  27.     public String getName() {  
  28.         return name;  
  29.     }  
  30.   
  31.     public void setName(String name) {  
  32.         this.name = name;  
  33.     }  
  34. }  
       junit类都是idea编译环境给我们配置好了,这里我们要注意,要使用getCurrentSession()来操作的话,我们首先要在Junit类中加上@Transaction注解,下面是相关的测试方法:

[java] view plain copy
  1. @Test  
  2. public void testGetOrLoad() {  
  3.     Session session = sessionFactory.getCurrentSession();  
  4.     StudentEntity student = (StudentEntity)session.get(StudentEntity.class1);  
  5.   
  6.     //StudentEntity student_load = (StudentEntity)session.load(StudentEntity.class,1);   String name = student.getName();  
  7. }  
      先测试get方法,我们发现一旦我们只是拿student这个实体操作,get方法是会输出相关的sql查询语句的,而我们注释掉get方法,换load方法的话,load方法执行拿student这个实体的数据是没有输出相应的sql语句的。但是我们在对student类进行操作的时候,这时才输出相关的语句.

      所以我们看出get()和load()之间的差别:

      get()每次执行都会执行sql语句,不会延迟。load()方法只是会在我们对拿到的实体进行操作的时候才去执行查询,拿到相应的实体信息。load方法返回的是一个代理对象(马士兵老师视频)。无论是get还是load首先都会查一级缓存(session)中有没有相应的对应值,如果没有,再去数据库进行查找。

     

      clear()方法是对session里面的缓存进行了清理,测试这个方法我们可以根据下面的Junit进行测试:

[java] view plain copy
  1. @Test  
  2.    public void testClear() {  
  3.        Session session = sessionFactory.getCurrentSession();  
  4.        session.get(StudentEntity.class,1);  
  5.        session.clear();  
  6.        session.get(StudentEntity.class,1);  
  7.    }  
     如果我们把session.clear()注释掉的话,我们就可以看到只执行了一条sql语句

   

    flush()方法是是对数据库同步的一条语句,执行完这个后立即刷新到数据库。粗浅的来看哈,其实里面还是有很多东西,比如FlushMode这个类,我们默认设置的是FlushMode.AUTO,这个一般不修改,只是为了以后的性能调优。其实我们在执行事务的时候,事务完成之后它会帮我们执行flush()方法。只是我们在进行大规模插入的时候,我们经常可以看到下面的操作:

[java] view plain copy
  1. Session session = sessionFactory.openSession();  
  2. Transaction tx = session.beginTransaction();     
  3. for ( int i=0; i<100000; i++ ) {      
  4. Customer customer = new Customer(.....);      
  5. session.save(customer);      
  6. if ( i % 20 == 0 ) {   
  7. //20, same as the JDBC batch size          
  8. //flush a batch of inserts and release memory:          
  9. session.flush();     
  10. session.clear();      
  11. }}     
  12. tx.commit();session.close();  
      这样做的目的就是避免大量插入,造成session里面内存溢出,所以我们定时清理一下就可以避免这个问题
阅读全文
0 0