广告
返回顶部
首页 > 资讯 > 数据库 >(20)Hibernate二级缓存
  • 904
分享到

(20)Hibernate二级缓存

2024-04-02 19:04:59 904人浏览 独家记忆
摘要

1、二级缓存的知识Hibernate提供的缓存:有一级缓存、二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!一级缓存:基于Session的缓存,缓存内容只在当前session有效,sessi


1、二级缓存的知识

Hibernate提供的缓存:有一级缓存二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!


一级缓存:基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效!

特点:作用范围较小! 缓存的时间短。缓存效果不明显。


二级缓存

Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据。 这个缓存也叫二级缓存。

Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可;不想用,直接移除,不影响代码。

如果用户觉得hibernate提供的框架不好用,可以换其他的缓存框架或自己实现缓存框架都可以。


下面的配置位于%hibernate%/project/etc/hibernate.properties中

##########################
### Second-level Cache ###
##########################

## disable the second-level cache 二级缓存默认不开启,需要手动开启
#hibernate.cache.use_second_level_cache false

## enable the query cache
#hibernate.cache.use_query_cache true 开启查询缓存

## choose a cache implementation 二级缓存框架的实现
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider


缓存的并发策略

<class-cache usage="read-only"/>     放入二级缓存的对象,只读; 
<class-cache usage="nonstrict-read-write"/>  非严格的读写
<class-cache usage="read-write"/>    读写; 放入二级缓存的对象可以读、写;
<class-cache usage="transactional"/>   (基于事务的策略)


2、使用二级缓存

二级缓存,使用步骤

    1)开启二级缓存

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

    2)指定缓存框架

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

    3)指定那些类加入二级缓存

<!-- 指定哪一些类,需要加入二级缓存 -->
<class-cache usage="read-write" class="com.rk.hibernate.cache.Department"/>
<class-cache usage="read-write" class="com.rk.hibernate.cache.Employee"/>
<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
<collection-cache usage="read-write" collection="com.rk.hibernate.cache.Department.emps"/>

    4)测试二级缓存!


示例代码和配置

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "Http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <!-- 通常,一个session-factory节点代表一个数据库 -->
    <session-factory>
        <!-- 1. 数据库连接配置 -->
        <property name="hibernate.connection.driver_class">com.Mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///test</property>	
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.passWord">root</property>
		<!-- 
			数据库方言配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
		 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        
        <!-- 2. 其他相关配置 -->
		<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 2.2 格式化sql -->
		<property name="hibernate.fORMat_sql">false</property>
		<!-- 2.3 自动建表  -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		

		<!--****************** 【二级缓存配置】****************** -->
		<!-- a. 开启二级缓存 -->
		<property name="hibernate.cache.use_second_level_cache">true</property>
		<!-- b. 指定使用哪一个缓存框架(默认提供的) -->
		<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
		<!-- 开启查询缓存 -->
		<property name="hibernate.cache.use_query_cache">true</property>
		<!-- c. 指定哪一些类,需要加入二级缓存 -->
		<class-cache usage="read-write" class="com.rk.hibernate.cache.Department"/>
		<class-cache usage="read-write" class="com.rk.hibernate.cache.Employee"/>
		<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
		<collection-cache usage="read-write" collection="com.rk.hibernate.cache.Department.emps"/>
		
    </session-factory>
</hibernate-configuration>

Department.java

package com.rk.hibernate.cache;

import java.util.Set;

public class Department
{
	private int deptId;
	private String deptName;
	private Set<Employee> emps;
	private int version;
	
	public int getVersion()
	{
		return version;
	}
	public void setVersion(int version)
	{
		this.version = version;
	}
	public int getDeptId()
	{
		return deptId;
	}
	public void setDeptId(int deptId)
	{
		this.deptId = deptId;
	}
	public String getDeptName()
	{
		return deptName;
	}
	public void setDeptName(String deptName)
	{
		this.deptName = deptName;
	}
	public Set<Employee> getEmps()
	{
		return emps;
	}
	public void setEmps(Set<Employee> emps)
	{
		this.emps = emps;
	}
	@Override
	public String toString()
	{
		return "Department [deptId=" + deptId + ", deptName=" + deptName + "]";
	}
	
}

Department.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.cache" auto-import="true">
	<class name="Department" table="T_Department">
		<!-- <cache usage="read-only"/> -->
		<id name="deptId" column="id">
			<generator class="native"></generator>
		</id>
		<version name="version" column="dept_version"></version>
		<property name="deptName" column="name" type="string"></property>
		<set name="emps" table="T_Employee">
			<!-- <cache usage="read-only"/> -->
			<key column="deptId"></key>
			<one-to-many class="Employee"/>
		</set>
	</class>

</hibernate-mapping>
	

Employee.java

package com.rk.hibernate.cache;

public class Employee
{
	private int empId;
	private String empName;
	private int salary;
	private Department dept;
	private int version;
	
	public int getVersion()
	{
		return version;
	}
	public void setVersion(int version)
	{
		this.version = version;
	}
	public int getEmpId()
	{
		return empId;
	}
	public void setEmpId(int empId)
	{
		this.empId = empId;
	}
	public String getEmpName()
	{
		return empName;
	}
	public void setEmpName(String empName)
	{
		this.empName = empName;
	}
	public int getSalary()
	{
		return salary;
	}
	public void setSalary(int salary)
	{
		this.salary = salary;
	}
	public Department getDept()
	{
		return dept;
	}
	public void setDept(Department dept)
	{
		this.dept = dept;
	}
	@Override
	public String toString()
	{
		return "Employee [empId=" + empId + ", empName=" + empName + ", salary=" + salary + "]";
	}
	
}

Employee.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.cache" auto-import="true">
	<class name="Employee" table="T_Employee">
		<!-- <cache usage="read-only"/> -->
		<id name="empId" column="id">
			<generator class="native"></generator>
		</id>
		<version name="version" column="emp_version"></version>
		<property name="empName" column="name" type="string"></property>
		<property name="salary" column="salary" type="int"></property>
		<many-to-one name="dept" column="deptId" class="Department"></many-to-one>
	</class>
</hibernate-mapping>

App.java

package com.rk.hibernate.cache;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;


public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Department.class)
						.addClass(Employee.class)
						.buildSessionFactory();
	}
	
	
	// 1. 测试二级缓存的使用
	//思路:sesion本身提供了一级缓存,它是mandatory,不能关闭
	//二级缓存,是optional,通过配置文件可以开启,可以关闭。
	//如果不开启二级缓存,两个session查询同一个id的数据,会发送两个SQL语句
	//如果开启二级缓存,两个session查询同一个id的数据,会发送一条SQL语句
	//通过开启和关闭二级缓存,来查看执行的SQL数目
	@Test
	public void testSecondLevelCache()
	{
		//第1次查询,第一个session
		Session session1 = sf.openSession();
		session1.beginTransaction();		
		Department dept1 = (Department) session1.get(Department.class, 3);
		Set<Employee> emps1 = dept1.getEmps();
		System.out.println(dept1);
		System.out.println(emps1);
		session1.getTransaction().commit();
		session1.close();
		
		System.out.println("-------------------------------");
		
		//第2次查询,第二个session
		Session session2 = sf.openSession();
		session2.beginTransaction();		
		Department dept2 = (Department) session2.get(Department.class, 3);
		Set<Employee> emps2 = dept2.getEmps();
		System.out.println(dept2);		
		System.out.println(emps2);
		session2.getTransaction().commit();
		session2.close();
	}
	
	
	@Test
	public void testQueryCache()
	{
		// 第1次查询,第一个session
		Session session1 = sf.openSession();
		session1.beginTransaction();
		// HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】
		Query q1 = session1.createQuery("from Department").setCacheable(true);
		List<Department> list1 = q1.list();
		System.out.println(list1);
		session1.getTransaction().commit();
		session1.close();

		System.out.println("-------------------------------");

		// 第2次查询,第二个session
		Session session2 = sf.openSession();
		session2.beginTransaction();
		// HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】
		Query q2 = session2.createQuery("from Department").setCacheable(true);
		List<Department> list2 = q2.list();
		System.out.println(list2);
		session2.getTransaction().commit();
		session2.close();
	}
	
}


当我们开启二级缓存后,例如在上面的testSecondLevelCache()方法中,第一次从Session读取数据后,会存储在二级缓存上;第二次打开Session,程序再进行相同查询,就不需要再发送SQL语句,因为它会从二级缓存中读取数据。


有一点需要注意如果二级缓存中没有数据,第一次开启Session读取数据,并调用session.clear()方法,再读取数据,会发送两次SQL语句


	@Test
	public void test1()
	{
		// 第1次查询,第一个session
		Session session1 = sf.openSession();
		session1.beginTransaction();
		Department dept1 = (Department) session1.get(Department.class, 2);
		System.out.println(dept1);	
		System.out.println(dept1.getEmps());
		
		session1.clear();
		dept1 = (Department) session1.get(Department.class, 2);
		System.out.println(dept1);	
		System.out.println(dept1.getEmps());
		
		session1.getTransaction().commit();
		session1.close();

	}

结果如下:

Hibernate: select department0_.id as id0_0_, department0_.dept_version as dept2_0_0_, department0_.name as name0_0_ from T_Department department0_ where department0_.id=?
Department [deptId=2, deptName=woqu]
Hibernate: select emps0_.deptId as deptId0_1_, emps0_.id as id1_, emps0_.id as id1_0_, emps0_.emp_version as emp2_1_0_, emps0_.name as name1_0_, emps0_.salary as salary1_0_, emps0_.deptId as deptId1_0_ from T_Employee emps0_ where emps0_.deptId=?
[Employee [empId=3, empName=TO_T_, salary=4]]
Hibernate: select department0_.id as id0_0_, department0_.dept_version as dept2_0_0_, department0_.name as name0_0_ from T_Department department0_ where department0_.id=?
Department [deptId=2, deptName=woqu]
Hibernate: select emps0_.deptId as deptId0_1_, emps0_.id as id1_, emps0_.id as id1_0_, emps0_.emp_version as emp2_1_0_, emps0_.name as name1_0_, emps0_.salary as salary1_0_, emps0_.deptId as deptId1_0_ from T_Employee emps0_ where emps0_.deptId=?
[Employee [empId=3, empName=TO_T_, salary=4]]


如果二级缓存中已经存在数据,第二次开启Session,调用session.clear(),再读取数据,并不会发送SQL语句。

	@Test
	public void test1()
	{
		Session session2 = sf.openSession();
		session2.beginTransaction();
		Department dept2 = (Department) session2.get(Department.class, 2);
		System.out.println(dept2);	
		System.out.println(dept2.getEmps());
		
		session2.getTransaction().commit();
		session2.close();
		
		System.out.println("-------------------------------");
		
		
		// 第1次查询,第一个session
		Session session1 = sf.openSession();
		session1.beginTransaction();
		Department dept1 = (Department) session1.get(Department.class, 2);
		System.out.println(dept1);	
		System.out.println(dept1.getEmps());
		
		session1.clear();
		dept1 = (Department) session1.get(Department.class, 2);
		System.out.println(dept1);	
		System.out.println(dept1.getEmps());
		
		session1.getTransaction().commit();
		session1.close();

		System.out.println("-------------------------------");
	}

结果如下:

Hibernate: select department0_.id as id0_0_, department0_.dept_version as dept2_0_0_, department0_.name as name0_0_ from T_Department department0_ where department0_.id=?
Department [deptId=2, deptName=woqu]
Hibernate: select emps0_.deptId as deptId0_1_, emps0_.id as id1_, emps0_.id as id1_0_, emps0_.emp_version as emp2_1_0_, emps0_.name as name1_0_, emps0_.salary as salary1_0_, emps0_.deptId as deptId1_0_ from T_Employee emps0_ where emps0_.deptId=?
[Employee [empId=3, empName=TO_T_, salary=4]]
-------------------------------
Department [deptId=2, deptName=woqu]
[Employee [empId=3, empName=TO_T_, salary=4]]
Department [deptId=2, deptName=woqu]
[Employee [empId=3, empName=TO_T_, salary=4]]
-------------------------------









您可能感兴趣的文档:

--结束END--

本文标题: (20)Hibernate二级缓存

本文链接: https://www.lsjlt.com/news/45562.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • (20)Hibernate二级缓存
    1、二级缓存的知识Hibernate提供的缓存:有一级缓存、二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!一级缓存:基于Session的缓存,缓存内容只在当前session有效,sessi...
    99+
    2022-10-18
  • Hibernate二级缓存的使用
    Hibernate的二级缓存是一种在应用程序和数据库之间缓存数据的机制,以提高应用程序的性能和响应速度。使用Hibernate的二级...
    99+
    2023-09-20
    Hibernate
  • 如何配置Hibernate二级缓存
    小编给大家分享一下如何配置Hibernate二级缓存,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Hibernate有很多值得学习的地方,这里我们主要介绍配置Hi...
    99+
    2023-06-17
  • 怎么解决Hibernate二级缓存
    这篇文章主要讲解了“怎么解决Hibernate二级缓存”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决Hibernate二级缓存”吧!一.Hibernate二级缓存策略的一般过程如下:...
    99+
    2023-06-17
  • hibernate怎么开启二级缓存
    要在Hibernate中开启二级缓存,需要完成以下步骤:1. 配置缓存提供程序:在Hibernate配置文件(通常是hibernat...
    99+
    2023-08-24
    hibernate
  • 如何使用Hibernate 3二级缓存
    这篇文章将为大家详细讲解有关如何使用Hibernate 3二级缓存,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.Hibernate3的二级缓存和session级别的缓存一样都只对实体对象做缓存,不对属...
    99+
    2023-06-17
  • hibernate二级缓存机制是什么
    Hibernate二级缓存机制是指在Hibernate框架中,通过配置第二级缓存来缓存对象的持久化状态,提高数据库访问性能。Hibe...
    99+
    2023-08-24
    hibernate
  • Hibernate 3中怎么实现二级缓存
    Hibernate 3中怎么实现二级缓存,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Hibernate 3二级缓存和session级别的缓存一样都只对实体对象做缓存,不对属性...
    99+
    2023-06-17
  • (10)Hibernate一级缓存
    1、为什么要用缓存?目的:减少对数据库的访问次数!从而提升hibernate的执行效率!2、Hibernate中缓存分类一级缓存、二级缓存3、一级缓存的概念1)Hibenate中一级缓存,也叫做sessio...
    99+
    2022-10-18
  • hibernate在java中使用如何实现二级缓存
    本篇文章为大家展示了hibernate在java中使用如何实现二级缓存,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Hibernate的二级缓存一、缓存概述缓存(Cache): 计算机领域非常通用的...
    99+
    2023-05-31
    hibernate 二级缓存 java
  • Hibernate一级缓存是什么
    本篇内容介绍了“Hibernate一级缓存是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在学习Hibernate中,我们都知道由于一级...
    99+
    2023-06-17
  • Mybatis缓存机制(一级缓存、二级缓存、三级缓存)
    一、含义: 缓存就是内存中的数据,常常来自对数据库查询结果的保存。 使用缓存,我们可以避免频繁与数据库进行交互,从而提高响应速度。 Mybatis的缓存分为一级缓存、二级缓存、三级缓存。 一...
    99+
    2023-09-02
    mybatis 缓存 java
  • JavaMybatis一级缓存和二级缓存
    目录一、什么是缓存 二、Mabtis一级缓存(1)测试一级缓存(2)清空一级缓存三、Mybatis二级缓存(1)开启二级缓存(2)测试二级缓存一、什么是缓存  &...
    99+
    2023-05-14
    Java Mybatis一级缓存和二级缓存 Mybatis一级缓存 Mybatis二级缓存
  • Hibernate一级缓存怎么使用
    这篇文章主要介绍“Hibernate一级缓存怎么使用”,在日常操作中,相信很多人在Hibernate一级缓存怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Hibernate一级缓存怎么使用”的疑惑有所...
    99+
    2023-06-17
  • Hibernate缓存
    一、Hibernate缓存概述Hibernate中提供两个级别的缓存,一级缓存和二级缓存。1.一级缓存是Session级别的缓存,它属于事物范围的缓存,一级缓存有hibernate进行管理。2.二级缓存是s...
    99+
    2022-10-18
  • spring boot 中的hibernate怎么使用ehcache 2.x实现二级缓存
    今天就跟大家聊聊有关spring boot 中的hibernate怎么使用ehcache 2.x实现二级缓存,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。项目依赖<depend...
    99+
    2023-05-31
    springboot hibernate ehcache 2.x
  • Mybatis 一级缓存与二级缓存的实现
    mybatis缓存 mybatis作为一个流行的持久化工具,缓存必然是缺少不了的组件。通过这篇文章,就让我们来了解一下mybatis的缓存。 mybatis缓存类型 说起mybati...
    99+
    2022-11-12
  • mybatis一级缓存和二级缓存是什么
    mybatis一级缓存和二级缓存是mybatis提供的两种不同层次的缓存机制,一级缓存是mybatis中默认开启的缓存机制,它是基于线程的本地缓存,二级缓存是基于namespace级别的缓存,可以被多个SqlSession对象共享。本教程操...
    99+
    2023-08-09
  • Spring中一级缓存、二级缓存和三级缓存有什么作用
    今天小编给大家分享一下Spring中一级缓存、二级缓存和三级缓存有什么作用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。缓存...
    99+
    2023-06-29
  • MyBatis中一级缓存与二级缓存的区别
    今天就跟大家聊聊有关MyBatis中一级缓存与二级缓存的区别,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一级缓存一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sq...
    99+
    2023-05-31
    mybatis 一级缓存 二级缓存
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作