<!-- 使用二级缓存,默认是未打开的 -->
<!-- 指定要使用的缓存的要提供的供应商,这也就打开了二级缓存 -->
<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();
}
}
}