Hibernate(十)__缓存机制

为什么需要缓存?

缓存的作用主要用来提高性能,可以简单的理解成一个Map;

使 用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、 删除缓存中的无效数据。

从上图看出: 当我们去查询对象的时候,首先到一级缓存去取数据,如果有,则不到数据库中取,

如果没有则到数据库中取,同时在一级缓存中放入对象。

一级缓存,Session级共享

save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中,

一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。

① 什么操作会向一级缓存放入数据?

save,update,saveOrUpdate,load,get,list,iterate,lock

首先save放入一级缓存,commit提交后才会将数据存入数据库中。

② 什么操作会从一级缓存取出数据?

get / load

get / load 会首先从一级缓存中取,如没有.再有不同的操作

[get 会立即向数据库发请求,而load 会返回一个代理对象,直到用户真的去使用数据,才会向数据库发请求]

list 会不会从session缓存取数据。

③一级缓存不需要配置,就可以使用,它本身没有保护机制,所以我们程序员要考虑这个问题,我们可以同 evict 或者 clear来清除session缓存中对象. evict 是清除一个对象,clear是清除所有的sesion缓存对象

session.evict(obj);

Session.clear();

④session级缓存中对象的生命周期, 当session关闭后,就自动销毁.

我们自己HashMap来模拟一个Session缓存,加深对缓存的深入

package com.hsp.view;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyCache {
    //使用map来模拟缓存
    static Map<Integer,Student> maps=new HashMap<Integer,Student>();

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        getStudent(1);
        getStudent(1);
        getStudent(1);
        getStudent(1);
        getStudent(3);
        getStudent(3);
    }

    public static Student getStudent(Integer id){  //s.get()
        //先到缓存去
        if(maps.containsKey(id)){
            //在缓存有
            System.out.println("从缓存取出");
            return maps.get(id);
        }else{
            System.out.println("从数据库中取");
            //到数据库取
            Student stu=MyDB.getStudentFromDB(id);
            //放入缓存
            maps.put(id, stu);
            return stu;
        }
    }
}

//我的数据库
class MyDB{

    static List<Student> lists=new  ArrayList<Student>();

    //初始化数据库,假设有三个学生
    static{
        Student s1=new Student();
        s1.setId(1);
        s1.setName("aaa");
        Student s2=new Student();
        s2.setId(2);
        s2.setName("bbb");
        Student s3=new Student();
        s3.setId(3);
        s3.setName("ccc");
        lists.add(s1);
        lists.add(s2);
        lists.add(s3);

    }

    public static Student getStudentFromDB(Integer id){
        for(Student s: lists){
            if(s.getId().equals(id)){
                return s;
            }
        }
        return null;// 在数据库中没有
    }
}

class Student{
    private Integer id;
    private String name;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

 二级缓存,SessionFacotry级共享

为什么需要二级缓存?

因为一级缓存有限(生命周期短),所以我们需要二级缓存(SessionFactory缓存)来弥补这个问题

  1. 需要配置
  2. 二级缓存是交给第三方去处理,常见的Hashtable , OSCache , EHCache
  3. 二级缓存的原理

访问小明的信息后就会将对象同时存放到一级和二级缓存中。

4.二级缓存的对象可能放在内存,也可能放在磁盘.

如何配置使用二级缓存?

1.将oscache-2.1.jar放入lib文件夹中,同时将log4j-1.2.14.jar引入lib文件夹。

2.在hibernate.cfg.xml文件中进行配置

<property name="cache.use_second_level_cache">true</property>

<!-- 指定使用哪种二级缓存 -->

<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>

<!--启用查看命中率 -->
<property name="hibernate.generate_statistics">true</property>

<!-- 指定管理的对象映射文件 -->

<mapping resource="com/xidian/domain/Message.hbm.xml" />

<mapping resource="com/xidian/domain/Users.hbm.xml" />

<!--指定哪个domain启用二级缓存  -->

<class-cache class="com.xidian.domain.Users" usage="read-write"/> <!-- 指定哪个domain启用二级缓存-->

特别说明二级缓存策略:

■  只读缓存(read-only)

      ■ 读写缓存(read-write) [ 银行,财务软件]

      ■ 不严格读写缓存(nonstrict-read-write) [bbs 被浏览多少次]

      ■ 事务缓存(transactional)

3. 可以将oscache.properties文件放在 src目录下,这样你可以指定放入二级缓存的对象capacity 大小. 默认1000。

//完成一个统计,统计的信息在Sessfactory

//SessionFactory对象.

Statistics statistics= HibernateUtil.getSessionFactory().getStatistics();

System.out.println(statistics);

System.out.println("放入"+statistics.getSecondLevelCachePutCount());

System.out.println("命中"+statistics.getSecondLevelCacheHitCount());

System.out.println("错过"+statistics.getSecondLevelCacheMissCount());

未解决问题:

Users stu1=(Users) s.get(Users.class, 1);

s.evict(stu1);

Users stu2=(Users) s.get(Users.class,1);

Hibernate发了两次sql语句

这种情况下放入1 命中0 错过2

第一次查询时会错过一次,向数据库中发sql语句,然后放入一次。然后将对象stu1在session中删除,

这个时候应该是一级缓存中没有二级缓存中有。第二次再次查询的时候,又错过了一次,

然后又向数据库中发sql语句进行查询。不知道为什么?

第二次查询的时候应该在一级缓存中没有找到的情况下找到二级缓存并击中一次。

hibernate总结:

时间: 2024-08-05 04:42:07

Hibernate(十)__缓存机制的相关文章

hibernate回顾之缓存机制-一级缓存、二级缓存、查询缓存

在介绍hibernate的缓存机制前,我们先了解一下什么是缓存: 缓存(Cache): 计算机领域非常通用的概念.里面放东西,说白了缓存就是一个集合.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数据是数据存储源中数据的拷贝并且缓存的物理介质通常是内存. 了解jdbc的人都知道,当需要连接数据库时,一般都会做一个连接池,那么连接池和缓存有什么区别呢? 相同点:两者都可以是在内存里,实现时一样的

hibernate中的缓存机制

一.为什么要用Hibernate缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 二.Hibernate缓存原理是怎样的?Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存. 1.Hibernate一级缓存又称为“Session的缓存”. Sessio

Hibernate学习之缓存机制

转自:http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 一.N+1问题 首先我们来探讨一下N+1的问题,我们先通过一个例子来看一下,什么是N+1问题:list()获得对象: /** * 此时会发出一条sql,将30个学生全部查询出来 */ List<Student> ls = (List<Student>)session.createQuery("from Student") .setFirstResu

分享知识-快乐自己:论Hibernate中的缓存机制

Hibernate缓存 缓存: 是计算机领域的概念,它介于应用程序和永久性数据存储源之间. 缓存: 一般人的理解是在内存中的一块空间,可以将二级缓存配置到硬盘.用白话来说,就是一个存储数据的容器.我们关注的是,哪些数据需要被放入二级缓存. 缓存作用: 降低应用程序直接读写数据库的频率,从而提高程序的运行性能.缓存中的数据是数据存储源中数据的拷贝.缓存的物理介质通常是[内存]. Hibernate缓存分类: 1):Session缓存(又称作事务缓存):Hibernate内置的,不能卸除. 缓存范围

Hibernate(十四)缓存

一.什么是缓存 缓存是介于应用程序和永久必数据存储源之间,目的是为了降低应用程序直接读写永久必数据存储源的频率,从而提高运行性能 缓存通常是在内存中的如: Office中的Word.excel Hibernater中的Session以及SessionFactory 二.对旬在JVM中的生命周期 new 语句创建JAVA对象时,JVM会为当前对象分配一个内存 只要当前对象被其它资源引用,就会一直存在内存中 如果当前对象不被其它资源引用,就结结束生命周期 一个对象被其它生命周期未结束的对象引用,则这

hibernate中缓存机制

1.一级缓存是针对session级别的,当这个session关闭后这个缓存就不存在了.2.二级缓存是SessionFactory级别的,二级缓存我们通常使用其他的一些开源组件,比如hibernate经常使用的就是ECache,这个缓存在整个应用服务器中都会有效的. 区别:两者的作用范围不同. 首先要明白缓存是干什么的,缓存就是要将一些经常使用的数据缓存到内存或者各种储存介质中,当再次使用时可以不用去数据库中查询,减少与数据库的交互,提高性能.再说明一级与二级缓存的作用:一级缓存是Session级

浅谈Hibernate缓存机制:一级缓存、二级缓存

一:什么是缓存机制 当我们频繁访问数据库时,尤其像Hibernate持久层框架,会导致数据库访问性能降低,因此我们期望有一种机制能提供一个"缓存空间",我们将需要的数据复制到这个"缓存空间",当数据查询时,我们先在这个"缓存空间"里找,如果没有,我们再去数据库查找,这样就减少了与数据库的访问,从而提高了数据库访问性能,这就是缓存机制. 二:Hibernate缓存机制 1:一级缓存:Hibernate默认的缓存机制,它属于Session级别的缓存机

【Hibernate 7】浅谈Hibernate的缓存机制

一.Hibernate缓存机制简介 对于Hibernate本身来说,它的缓存主要包括三部分:session缓存(一级缓存).二级缓存.查询缓存. 1.1,session缓存 随着session的关闭而消失,load.iterator操作,会从一级缓存中查找数据,如果找不到,再到数据库里面查找.Query.list操作,如果没有配置查询缓存,将直接从数据库中获取数据. 特点:只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有

Hibernate缓存机制剖析

Hibernate是基于缓存机制实现的.Hibernate的缓存包括:一级缓存.二级缓存和查询缓存. Hibernate中支持懒加载load,也支持及时加载get.Hibernate采用CGlib的动态代理实现延迟加载.延迟加载采用CGlib的Enhancer类动态生成类. 比较 下面对Hibernate中一级缓存.二级缓存.查询缓存机制做一个横向比较: 相同点: 1.均为缓存,均可在一定的条件下缓存数据: 2.Hibernate的查询实现,是基于缓存机制: 3.三种缓存方式的内部实现方式类似,