<!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>
<property name="connection.url">
jdbc:oracle:thin:@localhost:1521:orcl
</property>
<property name="connection.username">t10</property>
<property name="connection.password">t10</property>
<property name="connection.driver_class">
oracle.jdbc.OracleDriver
</property>
<!--方言 -->
<property name="dialect">
org.hibernate.dialect.Oracle9Dialect
</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- 在我们的项目中使用currentSession-->
<property name="current_session_context_class">thread</property>
<!-- 开启配置2级缓存 -->
<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> <!--加载我们配置的映射文件 全路径 -->
<mapping resource="cn/bdqn/bean/Dept.hbm.xml" />
<mapping resource="cn/bdqn/bean/Emp.hbm.xml" /> </session-factory>
</hibernate-configuration>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.bdqn.bean">
<class name="Emp">
<!-- 配置2级缓存策略 -->
<cache usage="read-only"/> <id name="empNo">
<generator class="assigned"/><!-- 手动给主键赋值 -->
</id>
<property name="empName"/>
<property name="job"/>
<property name="sal" column="salary"/>
<property name="hireDate"/>
<!-- 配置多对一关联
name:对应的是 本类中 关联关系的属性名
column:对应数据库中 两个表的 外键!
class:关联的实体类
-->
<many-to-one name="dept" column="DEPTNO" class="Dept"/>
</class>
</hibernate-mapping>
<ehcache>

<!-- java.io.tmpdir:临时系统文件!  可以换成自己创建的目录下 -->
<diskStore path="java.io.tmpdir"/> <!--
maxElementsInMemory:在内存中 最大的存储量 10000对象
eternal:是否永远不销毁
timeToIdleSeconds:当前缓存的数据闲置多少时间被销毁 以秒为单位
timeToLiveSeconds:当前缓存的数据超过多少时间被销毁 以秒为单位
overflowToDisk: 是否写入磁盘
diskPersistent:硬盘文件是否永久保存
memoryStoreEvictionPolicy: 缓存清理策略: FIFO ,first in first out (先进先出). LFU , Less Frequently Used (最少使用).
意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。 LRU ,Least Recently Used(最近最少使用).
(ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,
而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
package cn.bdqn.test;

import java.util.ArrayList;
import java.util.List; import oracle.net.aso.s; import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.sun.org.apache.xml.internal.security.encryption.Transforms; import cn.bdqn.bean.Dept;
import cn.bdqn.bean.Emp;
import cn.bdqn.util.HibernateUtil; public class EmpTest { /**
* 1级缓存: session中的缓存
* clear():清空session中所有的缓存对象
* evict():清除session中指定的对象
*/ @Test
public void test01(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql
session.clear(); //清空缓存
emp = (Emp) session.get(Emp.class, 1); //产生1条sql
}
@Test
public void test02(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp = (Emp) session.load(Emp.class, 1);
session.clear(); //清空缓存
emp = (Emp) session.load(Emp.class, 1);
} @Test
public void test03(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp1 = (Emp) session.get(Emp.class, 1); //产生1条sql
Emp emp2 = (Emp) session.get(Emp.class, 2); //产生1条sql
session.evict(emp1); //清除指定的
} @Test
public void test04(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp=new Emp();
emp.setEmpNo(51);
emp.setEmpName("haha");
session.save(emp);
session.evict(emp); //清除指定的
transaction.commit(); // 能保存到数据库中吗? 肯定不能保存 除非把 session.evict(emp); 去掉
} @Test
public void test05(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp=new Emp();
emp.setEmpNo(52);
emp.setEmpName("haha");
session.save(emp); //持久态
System.out.println("********");
session.flush(); //产生sql语句 把 emp对象 同步到 数据库
System.out.println("********");
session.evict(emp); //清除指定的 但是 已经 清理了 缓存
transaction.commit(); // 能保存到数据库中,因为已经flush
} @Test
public void test06(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp=(Emp) session.get(Emp.class, 1); //持久化
emp.setEmpName("haha"); //emp 脏对象
System.out.println("flush前******************");
session.flush(); //同步数据库
System.out.println("flush后******************");
emp=(Emp) session.get(Emp.class, 1); //持久化
System.out.println(emp.getEmpName()); //输出 haha 证明同步到数据库中了
emp.setEmpName("heihei"); //emp 脏对象
transaction.commit();
} /**
* 2级缓存: 进程或者是集群范围内的缓存!是sessionFactory的缓存!
* 一个sessionFactory可以创建N个session!
* 也就是说 在2级缓存中的数据,N个session共享!
*
*
* 2级缓存适合存放的数据:
* 01.不经常被修改的数据
* 02.不敏感的数据 (财务数据不能放入)
* 03.共享的数据
*
*
* 配置ehCache缓存
* 01.引入jar
* 02.找到对应xml文件
* 03.在hibernate.cfg.xml文件中 开启和配置缓存
* 04.在对应的映射文件中 配置 缓存的策略
*/ @Test
public void test07(){ //之前是 两条sql语句
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql
session.clear(); //清空缓存
emp = (Emp) session.get(Emp.class, 1);
} /**
* 验证我们 映射文件中的 <cache usage="read-only"/>
*/
@Test
public void test08(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql
emp.setEmpName("hahaahaha");
session.update(emp);
transaction.commit(); //报错 can't writer to readonly object!!
} //java.io.tmpdir:临时系统文件! 可以换成自己创建的目录下
@Test
public void test09(){
System.out.println(System.getProperty("java.io.tmpdir"));
} /**
* 设置2级缓存 模式
* CacheMode.IGNORE: 不与2级缓存关联 产生2条sql
* CacheMode.NORMAL:与2级缓存关联,可读可写 产生1条sql
* CacheMode.GET:与2级缓存关联,只读 产生1条sql
* CacheMode.PUT:与2级缓存关联,只写 产生2条sql
* CacheMode.REFRESH:与2级缓存关联,只写
* 通过 hibernate.cache.use_minimal_puts 的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。
* 产生2条sql
*/
@Test
public void test10(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql
session.clear();
//设置缓存模式
session.setCacheMode(CacheMode.REFRESH);
emp = (Emp) session.get(Emp.class, 1); } /*
* 查询缓存
* 基于2级缓存!
* 第一次在网页中查询一个关键字 为 java的所有 页面 可能需要等待 2S
* 第2次在网页中查询一个关键字 为 java的所有 页面 必须 小于2S
*
* 01.去核心配置文件中配置
* <property name="cache.use_query_cache">true</property>
* 02.手动开启查询缓存
* query.setCacheable(true);
*/ @Test
public void test11(){
Session session = HibernateUtil.getCurrentSession();
Query query = session.createQuery("from Dept");
query.setCacheable(true); //首次开启 ! 之后如果还是这个query语句,那么就会启动查询缓存
List list = query.list();
for (Object object : list) {
System.out.println(object);
}
System.out.println("****************************");
Query query2 = session.createQuery("from Dept");
query2.setCacheable(true); //先去 查询缓存中查找
List list2 = query2.list();
for (Object object : list2) {
System.out.println(object);
}
System.out.println("****************************");
Query query3 = session.createQuery("from Dept");
//query3.setCacheable(true);
List list3 = query3.list();
for (Object object : list3) {
System.out.println(object);
}
session.close(); } }
05-13 02:28