什么是缓存??
答:缓存就是在内存中开辟一块空间,把本来要存放的数据放在此内存中,将来要用的时候直接去内存中取出来用。
什么是一级缓存???
答:一级缓存也就是session缓存。 一个session是不可以访问其他session的,这就会导致出一个问题,当多线程访问同一数据的时候,在不做二级缓存的情况下,每个线程都要开一个session,也就是每一个session都要发出一个sql语句,这时对性能很不好,处理的办法就是开启二级缓存。
什么是二级缓存???
答:二级缓存也就是SessionFactory级别的缓存,可以越过session的存在。。。。什么时候用: 数据改动不平凡, 数据量不大, 常常被访问。
打开二级缓存的步骤:
-
设定hibernate.cfg.xml文件
<!-- 使用二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </property>
-
@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; } }
-
测试代码
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默认是往二级缓存中加数据,但是查询的时候就不使用
重点:性能问题,先要考虑到本地内存取数据,不行再到本地硬盘读数据,再不行就到远程数据库中去读数据