hibernate二级缓存

hibernate二级缓存是建立在SessionFactory上面的,可以自己选择缓存提供商。而一级缓存只在session之内有效,session关闭缓存失效。

代码结构和使用的jar包

Department.java

package com.orange.demo;

import java.util.HashSet;
import java.util.Set;
/**
 * 部门实体
 * 部门和员工的关系是一对多 
 */
public class Department {
	private Integer departmentId;
	private String departmentName;
	private Set<Employee> employee = new HashSet<Employee>();
}


Employee.java

package com.orange.demo;
/**
 * 员工实体
 * 员工和部门的关系是多对一
 */
public class Employee {
	private Integer employeeId;
	private String employeeName;
	private Department department;

}


Department.hbm.xml

<?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="com.orange.demo">
	
	<class name="Department" table="t_department">
		<id name="departmentId" column="departmentId">
			<generator class="native"></generator>
		</id>
		<property name="departmentName" column="departmentName" type="string"></property>
		
		<!-- 
		部门和员工是一对多关系
		inverse属性:	默认为false,表示本方维护关联关系。如果为true,表示本方不维护关联关系。
		cascade=delete 删除部门时,同时将该部门的所有员工也删除,和inverse属性无关
		 -->
		<set name="employee" inverse="false" cascade="delete">
		 	<!-- 指定需要关联的列 -->
			<key column="departmentId"></key>
			<!--需要关联的表(类) -->
			<one-to-many class="Employee"/>
		</set>
	</class>
	
</hibernate-mapping>


Employee.hbm.xml

<?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="com.orange.demo">
	
	<class name="Employee" table="t_employee">
		<id name="employeeId" column="employeeId">
			<generator class="native"></generator>
		</id>
		<property name="employeeName" column="employeeName" type="string"></property>
		
		<!--相对于员工这一端是 多对一 -->
		<many-to-one name="department" class="Department" column="departmentId"></many-to-one>
	</class>
	
</hibernate-mapping>


Test.java

package com.orange.demo;

import java.util.Iterator;

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

public class Test {
	
	private static SessionFactory sessionFactory = null;
	static{
		Configuration cfg = new Configuration();
		cfg.configure("hibernate.cfg.xml");		//在src目录下
		sessionFactory = cfg.buildSessionFactory();
	}
	
	public static void main(String[] args) {
		try {
//			save();
			get1();
//			get2();
//			get3();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

//添加测试数据
	public static void save() throws Exception {
		Session session = sessionFactory.openSession();
		Transaction tx =  session.beginTransaction();
		Department department1 = new Department();
		department1.setDepartmentName("开发部");
		Department department2 = new Department();
		department2.setDepartmentName("测试部");
		
		Employee employee1 = new Employee();
		employee1.setEmployeeName("大橙子");
		Employee employee2 = new Employee();
		employee2.setEmployeeName("二橙子");
		Employee employee3 = new Employee();
		employee3.setEmployeeName("小王");
		
		
		//为员工添加部门
		employee1.setDepartment(department1);
		employee2.setDepartment(department1);
		employee3.setDepartment(department2);
		
		/*//开发部增加两名员工,大橙子和二橙子
		department1.getEmployee().add(employee1);
		department1.getEmployee().add(employee2);
		//测试部增加一名员工,小王
		department2.getEmployee().add(employee3);*/
		
		session.save(department1);	//需要被依赖的放在前面保存这里是员工需要依赖部门
		session.save(department2);
		session.save(employee1);
		session.save(employee2);
		session.save(employee3);
		
		tx.commit();
		session.close();
	
	}

	
	/**
	 * 测试员工缓存
	 */
	public static void get1() throws Exception {

		Session session = sessionFactory.openSession();
		session.beginTransaction();

		Employee employee1 = (Employee) session.get(Employee.class, 1); // 获取

		session.getTransaction().commit();
		System.out.println(employee1.getEmployeeName());
		session.close();

		Session session2 = sessionFactory.openSession();
		session2.beginTransaction();

		Employee employee2 = (Employee) session2.get(Employee.class, 1); // 获取
		System.out.println(employee2.getEmployeeName());

		session2.getTransaction().commit();
		session2.close();
	
	}
	/**
	 * 类中的集合增加缓存
	 *
	 */
	public static void get2() throws Exception {
		
		Session session1 = sessionFactory.openSession();
		session1.beginTransaction();
		
		Department department1 = (Department) session1.get(Department.class, 1); // 获取
		
		session1.getTransaction().commit();
		System.out.println(department1.getDepartmentName());
		System.out.println(department1.getEmployee());
		session1.close();
		
		Session session2 = sessionFactory.openSession();
		session2.beginTransaction();
		
		Department department2 = (Department) session2.get(Department.class, 1); // 获取
		System.out.println(department1.getDepartmentName());
		System.out.println(department2.getEmployee());
		session2.getTransaction().commit();
		session2.close();
		
	}
	
	/**
	 * hql查询使用缓存
	 * 需要调用iterate()方法
	 */
	public static void get3() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();

		Iterator<Employee> iterator = session.createQuery("FROM Employee e WHERE e.id<3").iterate();
		while (iterator.hasNext()) {
			Employee e = iterator.next();
			System.out.println(e.getEmployeeName());
		}

		session.getTransaction().commit();
		session.close();
		System.out.println("=========");
		Session session2 = sessionFactory.openSession();
		session2.beginTransaction();

		Iterator<Employee> iterator2 = session2.createQuery("FROM Employee e WHERE e.id<3").iterate();
		while (iterator2.hasNext()) {
			Employee e = iterator2.next();
			System.out.println(e.getEmployeeName());
		}

		session2.getTransaction().commit();
		session2.close();
	}
	
}


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 name="foo">
			<!-- 数据库方言 --> 
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/t1?characterEncoding=UTF-8</property>
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.username">root</property>
		<property name="hibernate.connection.password">123456</property>
		<!-- 在控制台打印SQL,但不能打印建表语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 打印SQL是否格式化 false:不格式化 -->
		<property name="hibernate.format_sql">false</property>
		<!--自动更新数据库结构 -->
		<property name="hbm2ddl.auto">update</property>
		<!-- 开启二级缓存 HashtableCacheProvider是hibernate自带的缓存,也可以用其他厂商缓存--> 
		<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
		
		<mapping resource="com/orange/demo/Department.hbm.xml"/>
		<mapping resource="com/orange/demo/Employee.hbm.xml"/>
	
	
	
	<!--为Employee类添加缓存 -->
		<class-cache usage="read-write" class="com.orange.demo.Employee"/>	 
	<!--为Department类添加缓存  -->
		<class-cache usage="read-write" class="com.orange.demo.Department"/>	
	<!--为Department类的Employee属性添加缓存   Employee是个集合   -->
		<collection-cache usage="read-write" collection="com.orange.demo.Department.employee"/>	
	</session-factory>
</hibernate-configuration>


 get3()方法中使用了Iterator获取数据,Iterator的工作原理是先查询复合条件的所有数据的id(select id from table where id<3),然后每条数据查询一次(select * from table where id =1),如果有100条就会查询100次,这就是传说中的n+1次,其中“n”是要查询数据的总数,“1”是查询复合条件的所有数据,所以在这些数据没有缓存的时候效率会非常低。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值