Hibernate---缓存

Hibernate---缓存

1、为什么要用Hibernate缓存?

Hibernate是一个持久层框架,经常访问物理数据库,为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。

2、Hibernate缓存分为几种?

(1)一级缓存:也叫作Session缓存,在同一个session调用get()或者load()方法的时候使用

(2)二级缓存:也叫作SessionFactory缓存,在同一个SesssionFactory中,不同Session调用get()或者load()方法的时候调用。二级缓存默认不打开。

(3)查询缓存:在使用hql查询的时候使用。查询缓存默认不打开。

3、使用缓存的步骤是什么?

(1)使用一级缓存,不需要格外的操作。在同一个session中查询用一条数据,便可知道它的存在。

(2)使用二级缓存需要进行的操作如下:

(a)在hibernate.cfg.xml中配置如下信息,来开启二级缓存:

	<!-- 开启二级缓存 -->
    	<property name="cache.use_second_level_cache">true</property>
    	<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    	<!-- /开启二级缓存 -->
(b)在需要缓存的类的映射文件(此处是User.hbm.xml)中配置如下信息:
	<cache usage="read-only"/>
(c)添加commons-logging-1.1.jar包

(3)使用查询缓存需要在hibernate.cfg.xml中配置如下信息,来开启查询缓存:

	<!-- 开启三级缓存 -->
    	<property name="cache.use_query_cache">true</property>
    	<!-- /开启三级缓存 -->

4、具体的实例如下:

package com.etc.dao;

import java.util.List;

import javax.security.auth.login.CredentialException;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

public class UserDAOTest {
	/**
	 * Description:一级缓存:session缓存,在session的开始和结束之间,查询同一条数据,只发起一次sql请求,第二次直接从缓存中取
	 * 一级缓存:是同一个session调用get()或者load()方法使用的
	 * 控制台打印的信息如下:
	 * Hibernate: 
	 * select
	 *   user0_.user_id as user1_0_0_,
	 *   user0_.user_name as user2_0_0_ 
	 * from
	 *   test.t_user user0_ 
	 * where
	 *   user0_.user_id=?
	 *	User [id=1, username=zoey1]
	 *	User [id=1, username=zoey1]
	 *	true
	 *	===============session关闭之后新建一个session====================
	 *Hibernate: 
	 *	select
	 *	    user0_.user_id as user1_0_0_,
	 *	    user0_.user_name as user2_0_0_ 
	 *	from
	 *	    test.t_user user0_ 
	 *	where
	 *	    user0_.user_id=?
	 *	User [id=1, username=zoey1]
	 * @author zoey
	 * @date 2017年7月28日
	 */
	@Test
	public void testSession(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		/**
		 * 第一次执行查询时,发起一次sql,从数据库查询中返回数据,
		 * 同时将这条数据放入session缓存中,也就是放在内存中作为副本
		 */
		User user1 = (User)session.get(User.class,1);
		System.out.println(user1);
		
		User user2 = (User)session.get(User.class,1);//第二次查询时,直接从缓存中查询,返回内存的副本
		System.out.println(user2);
		
		System.out.println(user1 == user2);//true,两者是同一个对象,地址都一样
		session.getTransaction().commit();
		
		System.out.println("===============session关闭之后新建一个session====================");
		Session session2 = sessionFactory.getCurrentSession();
		session2.beginTransaction();
		User user3 = (User)session2.get(User.class,1);//关闭session之后,查询同一条数据,仍旧会从数据库中查询,而不是直接从缓存中读取
		//不同session用的是不同的缓存
		System.out.println(user3);
		session2.getTransaction().commit();
	}
	/**
	 * Description:二级缓存:SessionFactory缓存,默认不开启,想要开启时需要在hibernate.cfg.xml中配置相应的参数
	 * <property name="cache.use_second_level_cache">true</property>
     * <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
     * 还需要在要缓存的类的映射文件中配置cache属性
     * <cache usage="read-only"/>
     * 还需要加入commons-logging-1.1.jar包
	 * 二级缓存:是不同的session调用get()或者load()方法使用的
	 * 控制台打印的信息如下:
	 * Hibernate: 
	 * select
	 *     user0_.user_id as user1_0_0_,
	 *     user0_.user_name as user2_0_0_ 
	 * from
	 *     test.t_user user0_ 
	 * where
	 *	    user0_.user_id=?
	 * User [id=1, username=zoey1]
	 * ===============session关闭之后新建一个session====================
	 * User [id=1, username=zoey1]
	 * @author zoey
	 * @date 2017年7月28日
	 */
	@Test
	public void testSessionFactory(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		
		session.beginTransaction();
		User user1 = (User)session.get(User.class,1);//首先会用一级缓存
		System.out.println(user1);
		session.getTransaction().commit();//session关闭之后,一级缓存失效,二级缓存开启,开始生效
		
		System.out.println("===============session关闭之后新建一个session====================");
		
		Session session2 = sessionFactory.getCurrentSession();
		session2.beginTransaction();
		User user2 = (User)session2.get(User.class,1);//先使用一级缓存查找,没有数据,再从二级缓存中查找,可以查找到数据
		System.out.println(user2);
		session2.getTransaction().commit();
	}
	/**
	 * Description:三级缓存:查询缓存:默认不开启,需要在hibernate.cfg.xml中配置相应的属性才开启
	 * <property name="cache.use_query_cache">true</property>
	 * 三级缓存:在hql调用的时候使用的
	 * 控制台打印的信息如下:
	 * Hibernate: 
	 * select
	 *     user0_.user_id as user1_0_,
	 *     user0_.user_name as user2_0_ 
	 * from
	 *     test.t_user user0_
	 * 10
	 * 10
	 * @author zoey
	 * @date 2017年7月28日
	 */
	@Test
	public void testQuery(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		String hql = "from User";//只有hibernate查询语句才能用三级缓存
		List<User>  userlist1 = session.createQuery(hql).setCacheable(true).list();//第一次查询时,从数据库中查询数据
		System.out.println(userlist1.size());
		
		//hql语句会进行字符串比较,如果hql查询语句相同,则不再从数据库中查询,而是从三级缓存中读取
		List<User>  userlist2 = session.createQuery(hql).setCacheable(true).list();//第二次查询时,直接从三级缓存中读取
		System.out.println(userlist1.size());
		
		session.getTransaction().commit();
	}
	
}
User.java类如下:

package com.etc.dao;

public class User {
	private int id;
	private String username;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + "]";
	}
	
	
}

User.hbm.xml映射文件如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.etc.dao.User" table="t_user" catalog="test">
		<!-- 在具体需要缓存的类中配置 cache -->
		<cache usage="read-only" />
		<id name="id" type="java.lang.Integer">
			<column name="user_id" />
			<generator class="native" />
		</id>
		<property name="username" type="java.lang.String">
			<column name="user_name" />
		</property>
	</class>
</hibernate-mapping>

hibernate.cfg.xml配置文件如下:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
    	<!-- 开启二级缓存 -->
    	<property name="cache.use_second_level_cache">true</property>
    	<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    	<!-- /开启二级缓存 -->
    	
    	<!-- 开启三级缓存 -->
    	<property name="cache.use_query_cache">true</property>
    	<!-- /开启三级缓存 -->
    	<property name="show_sql">true</property>
    	<property name="format_sql">true</property>
    	<!-- <property name="hbm2ddl.auto">create</property> -->
    	<property name="current_session_context_class">thread</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="myeclipse.connection.profile">com.mysql.jdbc.Driver</property>
    	<mapping resource="com/etc/dao/User.hbm.xml"/>
    </session-factory>

</hibernate-configuration>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值