`
jianchen
  • 浏览: 344909 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hibernate学习之第十四篇

阅读更多

hibernate的内部缓存

hibernate的缓存分为两级:一级缓存(session级)和二级缓存(sessionFactory级)
缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存,从缓存中获取数据,删除缓存中的无效数据。
一级缓存,Session级共享。
save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中。一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。
例:

Person p = (Person)s.get(Person.class, id);
Person p = (Person)s.get(Person.class, id);

 连续两次执行该语句,sql语句的select查询只有一句输出。说明其中一次查询是到缓存中拿数据的。

query不能够从缓存中取数据。从缓存中取数据的方法不多。把数据放到缓存中的方法有很多。

static void query(int id) {
        Session s = HibernateUtil.getSession();
        Transaction tx = s.beginTransaction();
        Worker worker = (Worker) s.get(Person.class, id);
        Worker worker2 = (Worker) s.get(Worker.class, id);
        tx.commit();
        System.out.println(worker.getWork_year());
    }
 

运行以上代码,执行的sql语句为:

Hibernate: select person0_.id as id8_0_, person0_.name as name8_0_, person0_.age as age8_0_, person0_.work_year as work1_9_0_, person0_.farm_name as farm1_10_0_, person0_.clazz_ as clazz_0_ from ( select null as work_year, id, age, name, null as farm_name, 0 as clazz_ from person union select work_year, id, age, name, null as farm_name, 1 as clazz_ from worker union select null as work_year, id, age, name, farm_name, 2 as clazz_ from farmer ) person0_ where person0_.id=?
 



执行了两次s.get(),但只有一条select语句,说明第二次是从缓存中取的数据。

session的evict方法用于清除对应的缓存对象。session的clear方法清除整个session缓存。
一级缓存的缺陷: 对缓存中的数据量没有限制。数据量的不断累积,造成内存溢出。 没有什么保护,共享的范围较小。缓存的时间较短暂。一般存在于一次请求中。


二级缓存,sessionFactory级共享
hibernate的二级缓存交给了第三方的缓存框架来处理。

打开hibernate的二级缓存,在hibernate配置文件中配置。不过默认二级缓存是打开的:
<property name="hibernate.cache.use_second_level_cache">true</property>

实现为可插拔,通过修改cache.provider_class参数来改变;
缓存提供者配置,一般是第三方缓存框架:
  <property name="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
在配置前要确认使用的缓存的jar包应该导入到项目中了。

还要配置需要缓存的类:方法有两种。
①在hibernate配置文件中指定:
<class-cache class="hibernatetest.User" include="all" usage="read-only"/>
类必须是全限定名。usage表示缓存的策略,有四个值可选。
注意: The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)" 缓存类的配置必须在maping文件配置的后面,否则会报错。
②在映射文件中指定:
<hibernate-mapping package="hibernatetest">
  <class name="User" table="`user`">
      <cache usage="read-only"/>
    <id name="id">
      <generator class="hilo"/>
    </id>
    .......

hibernate内置了对EhCache,OSCache,TreeCache,SwarmCache的支持,可以通过实现CacheProvider和Cache接口来加入Hibernate不支持的缓存实现。

验证:
 
public class Main {
static User query(int id) {
        User user = null;
        Session session = null;
        try {
            session = HibernateUtil.getSession();
            Transaction tx = session.beginTransaction();
            user = (User) session.get(User.class, id);
            System.out.println(user.getUserName());
            user = (User) session.get(User.class, id);
            tx.commit();
            session.clear();
        } finally {
            if (session != null) {
                session.close();
            }
        }

        Session s = null;
        try {
            s = HibernateUtil.getSession();
            Transaction txn = s.beginTransaction();
            user = (User) s.get(User.class, id);
            txn.commit();
        } finally {
            if (s != null) {
                s.close();
            }
        }
        return user;
    }
   public static void saveUser(User user) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        Name name = new Name();
        name.setFirstName("firstName");
        name.setLastName("lastName");
        user.setUserName(name);
        session.save(user);
        tx.commit();
        session.close();
    }

    public static void main(String[] args) {
        User user = new User();
        user.setBirthday(new Date());

        saveUser(user);
        query(1);
        Statistics st = HibernateUtil.getSessionFactory().getStatistics();
        System.out.println("put:"+st.getSecondLevelCachePutCount());
        System.out.println("hit:"+st.getSecondLevelCacheHitCount());
        System.out.println("miss:"+st.getSecondLevelCacheMissCount());
        System.out.println(st.getConnectCount());

    }
使用信息统计之前要在hibernate配置文件中配置:
 <property name="hibernate.generate_statistics">true</property>

不设置缓存会打印输出sql语句。我设置了缓存,却无法查询了,连一条select语句也没有。sql语句为:
Hibernate: insert into user (first_name, last_name, birthday, id) values (?, ?, ?, ?)
hibernatetest.Name@12a55aa
put:1
hit:2
miss:0

3

后来把user的主键生成方式改为native(一开始使用的hilo)
输出的sql语句为:
Hibernate: insert into user (first_name, last_name, birthday) values (?, ?, ?)
Hibernate: select user0_.id as id0_0_, user0_.first_name as first2_0_0_, user0_.last_name as last3_0_0_, user0_.birthday as birthday0_0_ from user user0_ where user0_.id=?
hibernatetest.Name@e0cc23
put:1
hit:1
miss:1

3

两次的结果不一样。这跟主键的生成方式有关。
分析:
session的save(这个方法不适合native生成方式的主键
对于native的主键生成方式而言,在程序中保存对象时,并没有把数据放到二级缓存中去。hibernate在查询数据时,先到session中,即一级缓存中查找,如果有就返回。如果没有找到,则到二级缓存中去找,如果找到则返回。如果还是没有找到,才会建立一条连接到数据库中去查询。在第一次查询时,两个缓存中都没有,所以会有一次miss。在通过建立连接获得数据时会在一级和二级中都进行缓存数据。所以打印出put:1 ,然后把session关闭后,一级缓存没有了。再次查询,虽然一级缓存没有相应的数据,但能够最终在二级缓存中获得数据,所以达到了一次命中,所以打印出了hit:1.
不过使用高低键的主键生成方式,会在save的时候,就会把数据放到缓存中去了。所以会有一次put。所以在每次查询时都能够在二级缓存中找到数据,所以命中了2次,打印出hit:2,miss:0。
结果也显示连接的次数为3次,我们的程序中获得3次session。


总结:
session的save(这个方法不适合native生成方式的主键)

update,saveOrUpdate,list,iterator,get,load以及Query,Criteria都会填充二级缓存,但只有(没打开查询缓存时)Session的iterator,get,load会从二级缓存中取数据(iterator可能存在N+1次查询)。

Query,Criteria(查询缓存)由于命中率较低,因为要查询语句一样,才会命中,这一般不常见。所以hibernate缺省是关闭;修改cache.use_query_cache为true打开对查询的缓存,并且调用query.setCacheable(true)或criteria。setCacheable(true)。
SessionFactory中提供了evictXXX()方法用来清除缓存中的内容。
统计信息打开generate_statistics,用sessionFactory.getStatistics()获取统计信息。

有时间可以去研究一下分布式缓存和中央缓存。
使用缓存的条件
1,读取大于修改
2,数据量不能超过内存容量
3,对数据要有独享的控制
4,可以容忍出现无效数据

分享到:
评论

相关推荐

    Hibernate中文学习资料

    本篇将主要围绕`Hibernate3中文参考手册`展开,深入探讨Hibernate的基础概念、配置、实体映射、查询语言以及其他关键特性。 1. **Hibernate概述** Hibernate是一个开源的ORM框架,它提供了对Java应用程序的数据库...

    Hibernate-api Hibernate文档

    这篇文档旨在提供对Hibernate API的深入理解,帮助开发者更高效地使用Hibernate进行数据库操作。 一、Hibernate概述 Hibernate是Java开发中广泛使用的ORM框架,它提供了一种在Java应用中持久化数据到关系数据库的...

    hibernate 4.1 core API 英文版

    本篇将详细解析Hibernate 4.1 Core API,帮助开发者深入理解其核心概念、类库和接口。 1. **对象关系映射(ORM)**:ORM是Hibernate的核心特性,它将Java对象与数据库表进行映射,使得程序员可以避免编写大量的SQL...

    Hibernate 用法实例

    本篇内容将通过丰富的实例来深入探讨Hibernate的核心概念和技术,帮助读者从入门到精通,掌握其所有主要用法。** ### 一、Hibernate 概述 Hibernate 提供了一种在Java应用程序中管理关系数据库模型的机制。它通过...

    来自Java Persistence With Hibernate的示例

    本篇将深入探讨“Java Persistence with Hibernate”的核心概念,并通过具体的示例来帮助理解其工作原理和使用方法。 一、Hibernate简介 Hibernate是一个开源的Java库,它提供了在Java应用程序中与关系数据库进行...

    hibernate中文帮助文档

    这篇中文帮助文档旨在为开发者提供详尽的指南,加速他们对Hibernate的理解和应用。 一、Hibernate概述 Hibernate是一个强大的工具,它消除了Java应用程序与SQL之间的直接耦合,使得开发人员可以更专注于业务逻辑,...

    Hibernate API帮助文档

    这篇文档将深入探讨Hibernate API的各个方面,帮助开发者更好地理解和使用它。 一、Hibernate体系结构 Hibernate主要由以下组件构成: 1. Configuration:负责读取配置文件,建立SessionFactory。 2. ...

    Hibernate基础全攻略

    本篇攻略将深入探讨Hibernate的基础知识,帮助初学者理解并掌握其核心概念。 1. ** Hibernate简介** Hibernate是一个开源的ORM框架,它允许开发人员在Java应用中使用面向对象的方式来处理数据库。通过提供对象与...

    hibernate文档

    **标题:“Hibernate文档”** ...通过阅读“Hibernate1.ppt”这个文件,你将有机会深入学习这些概念,并掌握如何在实际项目中应用Hibernate。理解并熟练运用这些知识点,将有助于提升你的Java EE开发技能。

    Hibernate入门(上)笔记.pdf.zip

    这篇笔记主要涵盖了Hibernate框架的基础知识,它是Java开发中用于对象关系映射(ORM)的热门工具。Hibernate允许开发者用Java对象来操作数据库,消除了传统的JDBC代码,提高了开发效率和代码的可维护性。 一、...

    Hibernate 中文API 入门和开发的好帮手

    这篇文档是Hibernate的中文API,为学习和使用Hibernate提供了一个直观且易于理解的参考。 一、Hibernate概述 Hibernate是Java领域中广泛使用的ORM框架,它将数据库的操作转换为对Java对象的操作,通过配置文件和...

    精通hibernate源码

    Hibernate的缓存管理是其性能优化的关键,可能会讲解第一级缓存(Session缓存),第二级缓存(SessionFactory缓存),以及查询缓存的工作原理和配置。 6. **Chapter 10:事务与并发控制** 事务管理是数据库操作的...

    java web技术开发大全(最全最新)

    第14章 Struts 2的标签库 第15章 Struts 2对AJAX的支持 第16章 用Struts 2实现注册登录系统 第3篇 Hibernate篇 第17章 Hibernate的Helloworld程序 第18章 配置Hibernate 第19章 Hibernate的会话与O/R映射 第20...

    Java.Web整合开发王者归来.part14.rar

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

    Java.Web整合开发王者归来.part12.rar

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

    Java.Web整合开发王者归来.part01

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

    Java.Web整合开发王者归来.part08.rar

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

    Java.Web整合开发王者归来.part09.rar

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

    Java.Web整合开发王者归来.part07.rar

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

    Java.Web整合开发王者归来.part13.rar

    第5篇为Hibernate框架篇;第6篇为Spring框架篇;第7篇为EJB与Web服务篇,内容包括EJB 3概述、JPA规范Web服务框架XFire等;第8篇为工具篇,内容包括在Java Web项目中常用的开源工具框架、主要有版本管理工具SVN、日志...

Global site tag (gtag.js) - Google Analytics