Hibernate_二级缓存2_二级缓存详解

		<!-- 使用二级缓存,默认是未打开的 -->
		<!-- 指定要使用的缓存的要提供的供应商,这也就打开了二级缓存 -->
		<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
		<!-- 开启使用查询缓存 -->
		<property name="cache.use_query_cache">true</property>
		<!-- 指定要使用二级缓存实体类 -->
		<class-cache usage="read-write" class="cn.itcast.l_second_cache.Employee" />
		<class-cache usage="read-write" class="cn.itcast.l_second_cache.Department" />
		<collection-cache usage="read-write"
			collection="cn.itcast.l_second_cache.Department.employee" />


<!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 name="foo">
		<!-- 配置数据库信息 -->
		<!-- 方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- mysql连接配置 -->
		<property name="connection.url">jdbc:mysql://localhost:3306/hibernate_20170423</property>
		<!-- 配置连接mysql驱动 -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<!-- mysql用户名 -->
		<property name="connection.username">root</property>
		<!-- mysql密码 -->
		<property name="hibernate.connection.password">root</property>

		<!-- 其它配置 -->
		<!-- 显示生成的SQL语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 格式化SQL语 -->
		<property name="hibernate.format_sql">false</property>

		<!-- create:先删除,再创建。 update:如果表不存在就创建,不一样就更新,一样就什么都不做。 create-dorp:初始化时创建表,SessionFactory执行close()时删除表。 
			validate:验证表结构是否一致,如果不一致,就抛异常。 -->
		<property name="hbm2ddl.auto">update</property>

		<!-- 设置默认事务隔离级别 隔离级别中文 隔离级别英文 对应的整数表示 读未提交 READ UNCOMMITED 1 读已提交 READ 
			COMMITED 2 可重复读 REPEATABLE READ 4 串行化(不可并发) SERIALIZEABLE 8 -->
		<property name="connection.isolation">2</property>

		<!-- c3p0连接池设定 -->
		<!-- 使用c3p0连接池 配置连接池提供的供应商 -->
		<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
		<!-- 在连接池中可用的数据库连接的最少数目 -->
		<property name="c3p0.min_size">5</property>
		<!-- 在连接池中所有数据库连接的最大数目 -->
		<property name="c3p0.max_size">20</property>
		<!-- 设定数据库连接时间,以秒为单位, 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
		<property name="c3p0.timeout">120</property>
		<!-- 每3000秒检查所有连接池中空闲连接 以秒为单位 -->
		<property name="c3p0.idle_test_period">3000</property>

		<!-- 使用二级缓存,默认是未打开的 -->
		<!-- 指定要使用的缓存的要提供的供应商,这也就打开了二级缓存 -->
		<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
		<!-- 开启使用查询缓存 -->
		<property name="cache.use_query_cache">true</property>
		<!-- 指定要使用二级缓存实体类 -->
		<class-cache usage="read-write" class="cn.itcast.l_second_cache.Employee" />
		<class-cache usage="read-write" class="cn.itcast.l_second_cache.Department" />
		<collection-cache usage="read-write"
			collection="cn.itcast.l_second_cache.Department.employee" />


		<!-- 导入映射文件 -->
		<!-- <mapping resource="cn/itcast/a_helloworld/User.hbm.xml" /> -->

	</session-factory>
</hibernate-configuration>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 导入包 -->
<hibernate-mapping package="cn.itcast.l_second_cache">
	<!-- 类名 -->
	<class name="Employee" table="employee">
		<!-- 指定当前类要使用二级缓存 
		<cache usage="read-write" /> -->
		
		<id name="id" type="integer" column="id_">
			<generator class="native" />
		</id>
		<property name="name" type="string" column="name_" />

		<!-- department属性,表达的是本类与Department的多对一的关系 -->
		<many-to-one name="department" class="Department" column="departmentId"></many-to-one>
	</class>
</hibernate-mapping>



package cn.itcast.l_second_cache;

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

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

/**
 * 应用程序操作类
 * 
 * @author 风清杨
 * @version V3.0
 * 
 */
public class App {
	private static SessionFactory sessionFactory = new Configuration()//
			.configure()//
			.addClass(Department.class)//
			.addClass(Employee.class)//
			.buildSessionFactory();

	// 测试一级缓存(一级缓存[查询出二条查询语句])
	@Test
	public void testSessionCache() throws Exception {
		// ====================================第1个Session
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// ------------------------------------

			// 获取一方数据,并显示另一方信息
			Employee employee = (Employee) session.get(Employee.class, 1);
			// System.out.println(employee);

			// ------------------------------------
			tx.commit();
		} catch (RuntimeException e) {
			tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		// ====================================第二2个Session
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = null;
		try {
			tx2 = session2.beginTransaction();
			// ------------------------------------

			// 获取一方数据,并显示另一方信息
			Employee employee2 = (Employee) session2.get(Employee.class, 1);
			// System.out.println(employee2);

			// ------------------------------------
			tx2.commit();
		} catch (RuntimeException e) {
			tx2.rollback();
			throw e;
		} finally {
			session2.close();
		}
	}

	// 测试二级缓存
	@Test
	public void testSecodeCache() throws Exception {
		// ====================================第1个Session
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// ------------------------------------

			// 获取一方数据,并显示另一方信息
			Department department = (Department) session.get(Department.class, 1);
			System.out.println(department.getName());
			System.out.println(department.getEmployee());

			// ------------------------------------
			tx.commit();
		} catch (RuntimeException e) {
			tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		// ====================================第二2个Session
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = null;
		try {
			tx2 = session2.beginTransaction();
			// ------------------------------------

			// 获取一方数据,并显示另一方信息
			Department department2 = (Department) session2.get(Department.class, 1);
			// department2.setName("研发部");
			System.out.println(department2.getName());
			System.out.println(department2.getEmployee());

			// ------------------------------------
			tx2.commit();
		} catch (RuntimeException e) {
			tx2.rollback();
			throw e;
		} finally {
			session2.close();
		}
	}

	// 测试查询缓存
	// 当使用Query.list()时,默认不会使用二级缓存
	@Test
	public void testQueryCache() throws Exception {
		// ====================================第1个Session
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// ------------------------------------

			List<Employee> list = session.createQuery("from Employee e where e.id<10").list();
			System.out.println(list);

			Employee employe5 = (Employee) session.get(Employee.class, 5);
			System.out.println(employe5);

			// ------------------------------------
			tx.commit();
		} catch (RuntimeException e) {
			tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		// ====================================第二2个Session
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = null;
		try {
			tx2 = session2.beginTransaction();
			// ------------------------------------

			List<Employee> list2 = session2.createQuery("from Employee e where e.id<10").list();
			System.out.println(list2);

			// ------------------------------------
			tx2.commit();
		} catch (RuntimeException e) {
			tx2.rollback();
			throw e;
		} finally {
			session2.close();
		}
	}

	// 测试查询缓存
	// 在使用HQL方式查询时,如果用iterate()方法,就会使用缓存
	// 因为这个方法是先查询所有符合条件的id集合,再一个一个的按id查找数据,就能用上缓存了。
	// 但是这个方法会有N+1次查询的问题,提升性能有限,不太常用
	@Test
	public void testQueryCache2() throws Exception {
		// ====================================第1个Session
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// ------------------------------------

			Iterator<Employee> iterator = session.createQuery("from Employee e where e.id<10").iterate();
			while (iterator.hasNext()) {
				Employee e = iterator.next();
				System.out.println(e);
			}

			Employee employe5 = (Employee) session.get(Employee.class, 5);
			System.out.println(employe5);

			// ------------------------------------
			tx.commit();
		} catch (RuntimeException e) {
			tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		// ====================================第二2个Session
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = null;
		try {
			tx2 = session2.beginTransaction();
			// ------------------------------------

			Iterator<Employee> iterator2 = session2.createQuery("from Employee e where e.id<10").iterate();
			while (iterator2.hasNext()) {
				Employee e = iterator2.next();
				System.out.println(e);
			}

			// ------------------------------------
			tx2.commit();
		} catch (RuntimeException e) {
			tx2.rollback();
			throw e;
		} finally {
			session2.close();
		}
	}

	// 测试查询缓存
	@Test
	public void testQueryCache3() throws Exception {
		// ====================================第1个Session
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// ------------------------------------

			List<Employee> list = session.createQuery(//
					"from Employee e where e.id<8")//
					.setCacheable(true)// 是否使用查询缓存,需要在hibernate.cfg.xml中开启查询缓才行
					.list();
			System.out.println(list);

			// ------------------------------------
			tx.commit();
		} catch (RuntimeException e) {
			tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		// ====================================第二2个Session
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = null;
		try {
			tx2 = session2.beginTransaction();
			// ------------------------------------
			System.out.println("\n------------------\n");

			List<Employee> list2 = session2.createQuery(//
					"from Employee e where e.id<8")//
					.setCacheable(true)//
					.list();
			System.out.println(list2);

			// ------------------------------------
			tx2.commit();
		} catch (RuntimeException e) {
			tx2.rollback();
			throw e;
		} finally {
			session2.close();
		}
	}

	// 测试Update与Delete格式的HQL语句对二级缓存的影响
	// 会让二级缓存中相关的数据失效,下次使用这些数据时会重新到数据库中加载
	@Test
	public void testUpdateTimestampCache() throws Exception {
		// ====================================第1个Session
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// ------------------------------------

			Employee employee = (Employee) session.get(Employee.class, 1);
			System.out.println(employee.getName());

			int update = session.createQuery("update Employee e set e.name=:Name where e.id=:Id")//
					.setParameter("Name", "张三1")//
					.setParameter("Id", 1)//
					.executeUpdate();// 执行更新

			// 再显示这个员工的名称
			// session.refresh(employee);
			System.out.println(employee.getName());
			// ------------------------------------
			tx.commit();
		} catch (RuntimeException e) {
			tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		// ====================================第二2个Session
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = null;
		try {
			tx2 = session2.beginTransaction();
			// ------------------------------------
			System.out.println("\n------------------\n");

			Employee employee2 = (Employee) session2.get(Employee.class, 1);
			System.out.println(employee2.getName());

			// ------------------------------------
			tx2.commit();
		} catch (RuntimeException e) {
			tx2.rollback();
			throw e;
		} finally {
			session2.close();
		}
	}
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值