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.導包

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目錄底下
<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()執行後會删除該檔案!!!
緩存操作
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 }
擷取統計資訊
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 }