天天看點

Hibernate(十)

1.批處理

1 //批處理 :批量處理
 2     //批量插入資料
 3     @Test
 4     public void addData(){
 5         Random random=new Random();
 6         for(int i=1;i<=100000000;i++){
 7             Teacher teacher=new Teacher();
 8             teacher.setTname(randomName());
 9             //teacher : 持久化狀态,持久化狀态的對象是放在Session的一級緩存中,因為一級緩存是放在記憶體中.(1億對象存放在記憶體中)
10             session.save(teacher);
11             // 當一級緩存中的對象達到一定數量,那就把一級緩存中的對象同步到底層的資料庫,再清空一級緩存,釋放記憶體
12             if(i%100==0){
13                 //把一級緩存中的對象同步到底層的資料庫.把session當中的資料刷到資料庫,真正的儲存
14                 session.flush();
15                 //清空一級緩存,釋放記憶體
16                 session.clear();
17                 //如果寫上邊兩句有問題,就加上下邊兩句
18                 transaction.commit();
19                 transaction = session.beginTransaction();
20             }
21         }
22     }      
1     //批量修改
 2     @Test
 3     public void test6(){
 4         for(int i=1;i<100000000;i++){
 5             Teacher teacher = (Teacher) session.get(Teacher.class, i);
 6             teacher.setTname(randomName());
 7             session.update(teacher);
 8             if(i%100==0){
 9                 session.flush();
10                 session.clear();
11                 transaction.commit();
12                 transaction=session.beginTransaction();
13             }
14         }
15     }      
1     //批量删除
 2     @Test
 3     public void test7(){
 4         for(int i=1;i<100000000;i++){
 5             Teacher teacher = (Teacher) session.get(Teacher.class, i);
 6             session.delete(teacher);
 7             if(i%100==0){
 8                 session.flush();
 9                 session.clear();
10                 transaction.commit();
11                 transaction=session.beginTransaction();
12             }
13         }
14     }      

 2.一級緩存Session

緩存的是對象

跟Session相關(存放在記憶體中).

預設是開啟的.

作用:提高CUD操作的性能.

操作一級緩存的方法:

boolean contains(Object object)

判斷Session的一級緩存中是否包含一個對象,包含的話這個對象就是持久化狀态。

void evict(Object object)

從Session的一級緩存中逐出一個對象.(該對象就不是持久化狀态的對象).

void flush()

将Session的一級緩存中的對象,同步到底層資料庫表中.(立即同步)

void clear()

清空Session的一級緩存,所有的持久化狀态的對象都清空。(釋放記憶體)

void close()

關閉Session,先調用flush(),再調用clear().

1     @Test
 2     public void test8(){
 3         //list與iterate的差別
 4         
 5         //1.list不讀取緩存,但是查詢結果放入緩存
 6         Query query = session.createQuery("select t from Teacher t where t.tid<?");
 7         List list = query.setParameter(0, 100).list();
 8         System.out.println("========================");
 9         //2.iterate 讀取緩存
10         Query query2 = session.createQuery("select t from Teacher t where t.tid<?");
11         query2.setParameter(0, 100);
12         Iterator iterator = query2.iterate();
13         while(iterator.hasNext()){
14             System.out.println(iterator.next());
15         }
16         System.out.println("========================");
17         Iterator iterator1 = query2.iterate();
18         while(iterator1.hasNext()){
19             System.out.println(iterator1.next());
20         }
21         //3.get/load 都會查詢緩存
22         Teacher teacher = (Teacher)session.get(Teacher.class, 100);
23         System.out.println(teacher.getTid()+teacher.getTname());
24         System.out.println("========================");
25         Teacher teacher1 = (Teacher)session.get(Teacher.class, 100);
26         System.out.println(teacher1.getTid()+teacher1.getTname());
27         System.out.println("========================");
28         Teacher teacher2 = (Teacher)session.load(Teacher.class, 100);
29         System.out.println(teacher2.getTid()+teacher2.getTname());
30         System.out.println("========================");
31         Teacher teacher3 = (Teacher)session.load(Teacher.class, 100);
32         System.out.println(teacher3.getTid()+teacher3.getTname());
33     }      

3.二級緩存ehcache

跟SessionFactory相關,因為SessionFactory存活的時間長。

預設是關閉的.

作用:提高查詢效率.

二級緩存中的對象存放到哪裡,這個需要配置.

一般會配置記憶體中存放一些對象,超出了記憶體中放存的對象個數,就寫入磁盤.

ehcache.xml (配置二級緩存對象存放的配置檔案).

A.導包

Hibernate(十)

B.開啟二級緩存

hibernate.cfg.xml配置檔案配置資訊:

<!-- 配置開啟二級緩存 -->
  <property name="hibernate.cache.use_second_level_cache">true</property>
  <!-- 配置二級緩存的提供商 -->
  <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
          

C.從官方project示例中拷貝一個ehcache.xml檔案到src目錄底下

Hibernate(十)
<ehcache>
    <!-- diskStore: 配置二級緩存中的對象磁盤存儲目錄   -->
    <diskStore path="C:\\ehcache"/>
     <!-- 配置預設緩存區:
         maxElementsInMemory : 配置二級緩存中的對象在記憶體中存放的最大數量.
         eternal : 二級緩存中的對象是否永久有效。true: 永久有效、false: 不是永久有效.
         timeToIdleSeconds :  配置二級緩存中的對象空閑的有效時間 120秒.
         timeToLiveSeconds :  配置二級緩存中的對象存活的有效時間 120秒.
         overflowToDisk : 配置二級緩存中的對象超出了記憶體中存放的最大數量,就寫入磁盤.
      -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!-- 配置命名的緩存區 -->
    <cache name="myCache"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />
</ehcache>      

D.配置哪些持久化類用二級緩存

 方式一:在hibernate.cfg.xml配置

<!-- 配置持久化類用二級緩存 -->
        <!-- region 不寫就指定用ehcache.xml中的defaultCache,寫了myCache就使用myCache名稱的  -->
        <class-cache usage="read-write" class="com.rong.entity.sql.Teacher" region="myCache"/>      

方式二:在持久化類上

1 package com.rong.entity.sql;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 import javax.persistence.Entity;
 7 import javax.persistence.FetchType;
 8 import javax.persistence.GeneratedValue;
 9 import javax.persistence.GenerationType;
10 import javax.persistence.Id;
11 import javax.persistence.OneToMany;
12 
13 import org.hibernate.annotations.Cache;
14 import org.hibernate.annotations.CacheConcurrencyStrategy;
15 
16 @Entity
17 @Cache(usage=CacheConcurrencyStrategy.READ_WRITE,region="myCache")
18 public class Teacher {
19     @Id
20     @GeneratedValue(strategy=GenerationType.AUTO)
21     private int tid;
22     private String tname;
23     @OneToMany(targetEntity=Student.class,fetch=FetchType.LAZY,mappedBy="teacher")
24     private Set<Student> students=new HashSet<Student>();
25     public int getTid() {
26         return tid;
27     }
28     public void setTid(int tid) {
29         this.tid = tid;
30     }
31     public String getTname() {
32         return tname;
33     }
34     public void setTname(String tname) {
35         this.tname = tname;
36     }
37     public Set<Student> getStudents() {
38         return students;
39     }
40     public void setStudents(Set<Student> students) {
41         this.students = students;
42     }
43 }      

 E.代碼查詢

1     public static void main(String[] args) {
 2         Configuration config = new Configuration().configure();
 3         ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties())
 4                 .build();
 5         SessionFactory factory = config.buildSessionFactory(serviceRegistry);
 6         // 第一個session
 7         Session session = factory.openSession();
 8         Transaction transaction = session.beginTransaction();
 9 
10         Object object = session.get(Teacher.class, 1);
11         System.out.println(object);
12 
13         Object object2 = session.get(Teacher.class, 2);
14         System.out.println(object2);
15 
16         transaction.commit();
17         session.close();
18 
19         // 第二個session
20         Session session1 = factory.openSession();
21         Transaction transaction1 = session1.beginTransaction();
22 
23         Object object1 = session1.get(Teacher.class, 1);
24         System.out.println(object1);
25 
26         transaction1.commit();
27         session1.close();
28         
29         //看效果,休眠60秒
30         try {
31             Thread.sleep(1000*60);
32         } catch (InterruptedException e) {
33             e.printStackTrace();
34         }
35         factory.close();
36     }      

生成緩存檔案,但factory.close()執行後會删除該檔案!!!

Hibernate(十)

 緩存操作

1     public static void main(String[] args) {
 2         Configuration config = new Configuration().configure();
 3         ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties())
 4                 .build();
 5         SessionFactory factory = config.buildSessionFactory(serviceRegistry);
 6         // 第一個session
 7         Session session = factory.openSession();
 8         Transaction transaction = session.beginTransaction();
 9 
10         Object object = session.get(Teacher.class, 1);
11         System.out.println(object);
12 
13         Object object2 = session.get(Teacher.class, 2);
14         System.out.println(object2);
15 
16         transaction.commit();
17         session.close();
18 
19         // 第二個session
20         Session session1 = factory.openSession();
21         Transaction transaction1 = session1.beginTransaction();
22 
23         Object object1 = session1.get(Teacher.class, 1);
24         System.out.println(object1);
25 
26         transaction1.commit();
27         session1.close();
28         
29         
30         
31         //擷取緩存對象
32         Cache cache = factory.getCache();
33         //清空二級緩存中所有對象
34 //        cache.evictAllRegions();
35         //從二級緩存中踢出指定的對象
36 //        cache.evictEntity(Teacher.class, 1);
37 //        cache.evictEntity("com.rong.entity.sql.Teacher", 1);
38         //從二級緩存中踢出指定類型所有的對象
39 //        cache.evictEntityRegion(Teacher.class);
40 //        cache.evictEntityRegion("com.rong.entity.sql.Teacher");
41         //判斷二級緩存中在是否包含一個對象
42         boolean s1 = cache.containsEntity(Student.class, 1);
43         boolean s2 = cache.containsEntity("com.rong.entity.sql.Student", 1);
44         System.out.println(s1);
45         System.out.println(s2);
46         
47         boolean t1 = cache.containsEntity(Teacher.class, 1);
48         boolean t2 = cache.containsEntity("com.rong.entity.sql.Teacher", 1);
49         System.out.println(t1);
50         System.out.println(t2);
51         
52         factory.close();
53     }      
Hibernate(十)

擷取統計資訊

  1.hibernate.cfg.xml配置

<!-- 配置生成二級緩存的統計資訊 -->
<property name="hibernate.generate_statistics">true</property>
<!-- 讓Hibernate4用更友好的方式格式化統計資訊 -->
<property name="hibernate.cache.use_structured_entries">true</property>      

  2.代碼

1     public static void main(String[] args) {
 2         Configuration config = new Configuration().configure();
 3         ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties())
 4                 .build();
 5         SessionFactory factory = config.buildSessionFactory(serviceRegistry);
 6         // 第一個session
 7         Session session = factory.openSession();
 8         Transaction transaction = session.beginTransaction();
 9 
10         Object object = session.get(Teacher.class, 1);
11         System.out.println(object);
12 
13         Object object2 = session.get(Teacher.class, 2);
14         System.out.println(object2);
15 
16         transaction.commit();
17         session.close();
18 
19         // 第二個session
20         Session session1 = factory.openSession();
21         Transaction transaction1 = session1.beginTransaction();
22 
23         Object object1 = session1.get(Teacher.class, 1);
24         System.out.println(object1);
25 
26         transaction1.commit();
27         session1.close();
28         
29         
30         
31         //擷取緩存對象
32         Cache cache = factory.getCache();
33         //清空二級緩存中所有對象
34 //        cache.evictAllRegions();
35         //從二級緩存中踢出指定的對象
36 //        cache.evictEntity(Teacher.class, 1);
37 //        cache.evictEntity("com.rong.entity.sql.Teacher", 1);
38         //從二級緩存中踢出指定類型所有的對象
39 //        cache.evictEntityRegion(Teacher.class);
40 //        cache.evictEntityRegion("com.rong.entity.sql.Teacher");
41         //判斷二級緩存中在是否包含一個對象
42         boolean s1 = cache.containsEntity(Student.class, 1);
43         boolean s2 = cache.containsEntity("com.rong.entity.sql.Student", 1);
44         System.out.println(s1);
45         System.out.println(s2);
46         
47         boolean t1 = cache.containsEntity(Teacher.class, 1);
48         boolean t2 = cache.containsEntity("com.rong.entity.sql.Teacher", 1);
49         System.out.println(t1);
50         System.out.println(t2);
51         
52         //擷取統計資訊
53         Statistics statistics = factory.getStatistics();
54         //命中的數量
55         long secondLevelCacheHitCount = statistics.getSecondLevelCacheHitCount();
56         System.out.println(secondLevelCacheHitCount);//1
57         //錯失的數量
58         long secondLevelCacheMissCount = statistics.getSecondLevelCacheMissCount();
59         System.out.println(secondLevelCacheMissCount);//2
60         //擷取老師的二級緩存的統計資訊
61         SecondLevelCacheStatistics scs = statistics.getSecondLevelCacheStatistics("com.rong.entity.sql.Teacher");
62         System.out.println(scs.getEntries());
63         
64         factory.close();
65     }      

 代碼查詢語句

  1.注意配置

<!-- 配置開啟查詢緩存 -->
<property name="hibernate.cache.use_query_cache">true</property>      

把查詢的結果放入緩存

1 List<Student> students = session.createQuery("select s from Student s join fetch s.teacher where s.age > ?")
 2 .setParameter(0, 30)
 3 .setCacheable(true) // 設定緩存查詢語句
 4 .list();
 5 
 6 
 7 List<Student> students = session.createQuery("select s from Student s join fetch s.teacher where s.age > ?")
 8 .setParameter(0, 20)
 9 .setCacheable(true) // 設定緩存查詢語句
10 .list();      

4.Session線程安全問題

如果是Hibernate3.1之前版本,它提供了HibernateUtil工具類可以擷取目前線程相關的Session.

如果是Hibernate3.1之後版本,它提供了可配置的方式,讓我們把Session配置成線程相關的Session.

A.在hibernate.cfg.xml中配置

<property name="hibernate.current_session_context_class">thread</property>      

B.代碼

1     public static void main(String[] args) {
 2         Configuration config = new Configuration().configure();
 3         ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties())
 4                 .build();
 5         SessionFactory factory = config.buildSessionFactory(serviceRegistry);
 6         // 第一個session
 7         Session session = factory.getCurrentSession();
 8         Transaction transaction = session.beginTransaction();
 9 
10         Object object = session.get(Teacher.class, 1);
11         System.out.println(object);
12 
13         Object object2 = session.get(Teacher.class, 2);
14         System.out.println(object2);
15 
16         transaction.commit();
17         //session.close();自動關閉,不用手動關閉
18         System.out.println(session);
19 
20         // 第二個session
21         Session session1 = factory.getCurrentSession();
22         Transaction transaction1 = session1.beginTransaction();
23 
24         Object object1 = session1.get(Teacher.class, 1);
25         System.out.println(object1);
26 
27         transaction1.commit();
28         //session1.close();自動關閉,不用手動關閉
29         System.out.println(session1);
30         
31         factory.close();
32     }