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

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     }
原文地址:https://www.cnblogs.com/57rongjielong/p/8351210.html