Hibernate 缓存问题

什么是缓存??

     答:缓存就是在内存中开辟一块空间,把本来要存放的数据放在此内存中,将来要用的时候直接去内存中取出来用。

什么是一级缓存???

     答:一级缓存也就是session缓存。   一个session是不可以访问其他session的,这就会导致出一个问题,当多线程访问同一数据的时候,在不做二级缓存的情况下,每个线程都要开一个session,也就是每一个session都要发出一个sql语句,这时对性能很不好,处理的办法就是开启二级缓存。

什么是二级缓存???

     答:二级缓存也就是SessionFactory级别的缓存,可以越过session的存在。。。。什么时候用:  数据改动不平凡, 数据量不大,  常常被访问。

打开二级缓存的步骤:

  1. 设定hibernate.cfg.xml文件

    <!-- 使用二级缓存 -->
            <property name="hibernate.cache.use_second_level_cache">true</property>
            <property name="hibernate.cache.provider_class">
            	org.hibernate.cache.EhCacheProvider
            </property>
     
  2. @Cache注解

    package com.lbx.model;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    import org.hibernate.annotations.BatchSize;
    import org.hibernate.annotations.Cache;
    import org.hibernate.annotations.CacheConcurrencyStrategy;
    
    @Entity
    //@BatchSize(size=2)
    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
    public class Category {
    	
    	private int id;
    	private String name;
    	
    	@Id
    	@GeneratedValue
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    }
     
  3. 测试代码

    package com.lbx.model.test;
    
    
    import java.util.List;
    
    import junit.framework.TestCase;
    
    import org.hibernate.Session;
    import org.hibernate.lucene.Text;
    
    import com.lbx.hibernate.Util.HibUtil;
    import com.lbx.model.Category;
    import com.lbx.model.Topic;
    
    public class Test extends TestCase {
    	
    	
    	// 测试缓存问题(session级缓存)
    	@Text
    	public void testCache01(){
    		Session session = HibUtil.getSession();
    		session.beginTransaction();
    		
    		//同一个session
    		Topic t1 = (Topic)session.load(Topic.class, 1);
    		System.out.println(t1.getTitle());
    		
    		Topic t2 = (Topic)session.load(Topic.class, 1);
    		System.out.println(t2.getTitle());
    		
    		session.beginTransaction().commit();
    		session.close();
    	}
    	
    	@Text
    	public void testCache02(){
    		Session session = HibUtil.getSession();
    		session.beginTransaction();
    		
    		Topic t1 = (Topic)session.load(Topic.class, 1);
    		System.out.println(t1.getTitle());
    		
    		session.beginTransaction().commit();
    		session.close();
    		
    		//一个session是不能访问其他session的
    		Session session2 = HibUtil.getSession();
    		session2.beginTransaction();
    		
    		Topic t2 = (Topic)session2.load(Topic.class, 1);
    		System.out.println(t2.getTitle());
    		
    		session2.beginTransaction().commit();
    		session2.close();
    	}
    	
    	//测试二级缓存
    	@Text
    	public void testCache03(){
    		Session session = HibUtil.getSession();
    		session.beginTransaction();
    		
    		Category t1 = (Category)session.load(Category.class, 9);
    		System.out.println(t1.getName());
    		
    		session.beginTransaction().commit();
    		session.close();
    		
    		//一个session是不能访问其他session的
    		Session session2 = HibUtil.getSession();
    		session2.beginTransaction();
    		
    		Category t2 = (Category)session2.load(Category.class, 9);
    		System.out.println(t2.getName());
    		
    		session2.beginTransaction().commit();
    		session2.close();
    	}
    	
    	//测试查询缓存(都只发一条sql语句)
    	@Text
    	public void testCache04(){
    		Session session = HibUtil.getSession();
    		session.beginTransaction();
    		
    		List<Category> lists1 = session.createQuery("from Category").setCacheable(true).list();
    		List<Category> lists2 = session.createQuery("from Category").setCacheable(true).list();
    		
    		session.beginTransaction().commit();
    		session.close();
    		
    		Session session2 = HibUtil.getSession();
    		session2.beginTransaction();
    		
    		List<Category> lists3 = session2.createQuery("from Category").setCacheable(true).list();
    		List<Category> lists4 = session2.createQuery("from Category").setCacheable(true).list();
    		
    		session2.beginTransaction().commit();
    		session2.close();
    		
    	}
    	
    }
     

注意:load默认是使用session缓存,iterate也是的,   list默认是往二级缓存中加数据,但是查询的时候就不使用

重点:性能问题,先要考虑到本地内存取数据,不行再到本地硬盘读数据,再不行就到远程数据库中去读数据

相关推荐