hibernate 一级缓存、二级缓存

来源:互联网 发布:嘉实红利优化混合 编辑:程序博客网 时间:2024/04/28 11:45

什么是缓存?
百度百科上这样定义的:缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行。
简单的讲就是在内存里划出一块空间,把本来存放到硬件的内容存放到内存里去,以后读这些内容的时候从内存中直接读。这就是缓存。
缓存就是要将一些经常使用的数据缓存到内存或者各种储存介质中,当再次使用时可以不用去数据库中查询,减少与数据库的交互,提高性能。

缓存分为一级缓存和二级缓存,一级缓存是Session级的缓存,二级缓存是SessionFactory级的缓存。
一级缓存示例如下:

public class HibernateCacheTest {    @Test public void save(){   Wife w=new Wife();   w.setName("sss");   Husband h=new Husband();   h.setName("aaaa");   w.setHusband(h);    Configuration config=new AnnotationConfiguration();    SessionFactory factory=config.configure().buildSessionFactory();    Session session=factory.getCurrentSession();    session.beginTransaction();     session.save(w);     session.save(h);    session.getTransaction().commit();    factory.close();    }    @Test    public void load(){        Configuration config=new AnnotationConfiguration();    SessionFactory factory=config.configure().buildSessionFactory();    Session session=factory.getCurrentSession();    session.beginTransaction();    Husband h=(Husband) session.load(Husband.class, 1);    System.out.println(h.getName());    Husband h1=(Husband) session.load(Husband.class, 1);    System.out.println(h1.getName());    session.getTransaction().commit();    factory.close();    }    @Test    public void load1(){        Configuration config=new AnnotationConfiguration();        SessionFactory factory=config.configure().buildSessionFactory();        Session session=factory.getCurrentSession();        session.beginTransaction();        Husband h=(Husband) session.load(Husband.class, 1);        System.out.println(h.getName());        session.getTransaction().commit();        factory.close();        Configuration config1=new AnnotationConfiguration();        SessionFactory factory1=config1.configure().buildSessionFactory();        Session session1=factory1.getCurrentSession();        session1.beginTransaction();        Husband h1=(Husband) session1.load(Husband.class, 1);        System.out.println(h1.getName());        session1.getTransaction().commit();        factory.close();    }}

执行load()方法,控制台打印结果如下:
sql语句只执行了一条,说明在同一个session里面有缓存,第二次直接在缓存中取的数据。

 Hibernate: select    husband0_.id as id0_0_,    husband0_.name as name0_0_ from    Husband husband0_ where    husband0_.id=? aaaa aaaa

执行load1()方法,控制台打印结果如下:
可以看到当session关闭,重新打开一个新的session后,又执行了一次sql语句。这说明一个session
是不能使用其他session 的缓存的。

select    husband0_.id as id0_0_,    husband0_.name as name0_0_ from    Husband husband0_ where    husband0_.id=?     aaaa select    husband0_.id as id4_0_,    husband0_.name as name4_0_ from    Husband husband0_ where    husband0_.id=?     aaaa

这样就会造成一个性能的问题,不同的session每个seesion都要取一次。假如我们多线程同时取这个对象,我们本来可以把这个对象放到内存中,但是因为多线程分布在不同的session中,所以我们每次都要到数据库中去取这个对象。
这就要引入SessionFactory来解决session解决不了的问题了。
使用二级缓存需要修改hibernate.cfg.xml:

      <!-- 使用二级缓存 -->        <property name="cache.use_second_level_cache">true</property>        <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider      </property>
  在Husband类中加注解@Cache:
  @Entity  @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)  public class Husband { private int id; private String name; @Id @GeneratedValuepublic 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;}}

这样再执行load1()方法时控制台只输出一次sql语句。

0 0
原创粉丝点击