Hibernate_15_缓存的使用
缓存是:当第一次查询时,会将已查询到的数据保存在缓存区,当再次查询符合条件的内容时,会首先从缓存中查找,如果找不到,在从数据库中加载。
本例中Department类、Employee类、SessionFactoryTools类与4中的相同。
Department.hbm.xml文件配置:
<hibernate-mapping package="cache"> <class name="Department" table="department"> <!-- 指定当前类要使用二级缓存 ,但不主张使用该方法, 主张在主配置文件中设置实体缓存类,便于管理 --> <!-- <cache usage="read-write" /> --> <id name="id" type="int" column="id"> <generator class="native" /> </id> <property name="name" type="string" column="name" length="20" /> <set name="employees" cascade="all"> <key column="departmentId"></key> <one-to-many class="Employee" /> </set> </class> </hibernate-mapping>
2)Employee.hbm.xml文件的配置:
<hibernate-mapping package="cache"> <class name="Employee" table="employees"> <!-- 指定当前类要使用二级缓存 ,但不主张使用该方法, 主张在主配置文件中设置实体缓存类,便于管理 --> <!-- <cache usage="read-write" /> --> <id name="id" type="int" column="id"> <generator class="native" /> </id> <property name="name" type="string" column="name" length="20" /> <many-to-one name="department" class="Departmen column="departmentId"> </many-to-one> </class> </hibernate-mapping>
3)主文件的配置:
<!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:///hibernate0</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="hibernate.connection.password"> root</property> <!-- 其他配置 --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">false</property> <property name="hbm2ddl.auto">update</property> <!-- 使用二级缓存,默认是未打开的。 --> <!-- 指定要使用的缓存的提供商,这也就打开了二级缓存 --> <property name="cache.provider_class"> org.hibernate.cache.HashtableCacheProvider </property> <!-- 开启使用查询缓存 ,必须在实体类使用缓存之前设置--> <property name="cache.use_query_cache">true</property> <!-- 映射文件配置 --> <mapping resource="cache/Employee.hbm.xml" /> <mapping resource="cache/Department.hbm.xml" /> <!-- 指定要使用二级缓存的实体类 --> <class-cache usage="read-only" class="cache.Employee" /> <class-cache usage="read-only" class="cache.Department" /> <!-- 使用集合的二级缓存 --> <collection-cache usage="read-write" collection="cache.Department.employees"/> </session-factory> </hibernate-configuration>
4)持久化层:
public class cacheDao { // 测试一级缓存(Session缓存) @Test public void testSessionCache() throws Exception { // ===================== 第1个Session Session session = SessionFactoryTools.getSession(); session.beginTransaction(); @SuppressWarnings("unused") Employee employee = (Employee) session.get(Employee.class, 1); session.getTransaction().commit(); session.close(); // ===================== 第2个Session Session session2 = SessionFactoryTools.getSession(); session2.beginTransaction(); @SuppressWarnings("unused") Employee employee2 = (Employee) session2.get(Employee.class, 1); session2.getTransaction().commit(); session2.close(); } // 测试二级缓存 @Test public void testSecondCache() throws Exception { // ===================== 第1个Session Session session = SessionFactoryTools.getSession(); session.beginTransaction(); <span style="white-space:pre"> </span>Department department = (Department) session.get(Department.class, 1); System.out.println(department.getName()); System.out.println(department.getEmployees()); session.getTransaction().commit(); session.close(); // ===================== 第2个Session Session session2 = SessionFactoryTools.getSession(); session2.beginTransaction(); <span style="white-space:pre"> </span>Department department2 = (Department) session2.get(Department.class, 1); System.out.println(department2.getName()); System.out.println(department2.getEmployees()); session2.getTransaction().commit(); session2.close(); } // 测试查询缓存 // 当使用Query.list()时,默认不会使用二级缓存 @Test public void testQueryCache() throws Exception { // ===================== 第1个Session Session session = SessionFactoryTools.getSession(); session.beginTransaction(); @SuppressWarnings("unchecked") List<Employee> list = session.createQuery("FROM Employee e WHERE e.id<10").list(); System.out.println(list); <span style="white-space:pre"> </span>Employee employee5 = (Employee) session.get(Employee.class, 5); System.out.println(employee5); session.getTransaction().commit(); session.close(); // ===================== 第2个Session Session session2 = SessionFactoryTools.getSession(); session2.beginTransaction(); @SuppressWarnings("unchecked") List<Employee> list2 = session2.createQuery("FROM Employee e WHERE e.id<10").list(); System.out.println(list2); session2.getTransaction().commit(); session2.close(); } // 测试查询缓存 // 当使用Query.list()时, // 手动设置使用查询缓存,就可以启用缓存 @Test public void testQueryCache2() throws Exception { // ===================== 第1个Session Session session = SessionFactoryTools.getSession(); session.beginTransaction(); List<?> list = session.createQuery("FROM Employee e WHERE e.id<9")// .setCacheable(true)// 设置是否使用查询缓存,并且需要在hibernate.cfg.xml中开启查询缓存才行 .list(); System.out.println(list); session.getTransaction().commit(); session.close(); System.out.println("\n------------------\n"); // ===================== 第2个Session Session session2 = SessionFactoryTools.getSession(); session2.beginTransaction(); List<?> list2 = session2.createQuery("FROM Employee e WHERE e.id<18")// .setCacheable(true)// 是否使用查询缓存 .list(); System.out.println(list2); session2.getTransaction().commit(); session2.close(); } // 测试查询缓存 // 在使用HQL方式的查询时,如果用iterate()方法,就会使用缓存。 // 因为这个方法是先查询所有符合条件的id集合,再一个一个的按id查找数据,就能用上缓存了。 // 但这个方法会有N+1次查询的问题,提升性能有限,不太常用。 @Test public void testQueryCache3() throws Exception { // ===================== 第1个Session Session session = SessionFactoryTools.getSession(); session.beginTransaction(); @SuppressWarnings("unchecked") Iterator<Employee> iterator = session.createQuery("FROM Employee e WHERE e.id<18").iterate(); while (iterator.hasNext()) { Employee e = iterator.next(); System.out.println(e); } <span style="white-space:pre"> </span>Employee employee5 = (Employee) session.get(Employee.class, 5); System.out.println(employee5); session.getTransaction().commit(); session.close(); System.out.println("\n--------------------------------\n"); // ===================== 第2个Session Session session2 = SessionFactoryTools.getSession(); session2.beginTransaction(); @SuppressWarnings("unchecked") Iterator<Employee> iterator2 = session2.createQuery("FROM Employee e WHERE e.id<10").iterate(); while (iterator2.hasNext()) { Employee e = iterator2.next(); System.out.println(e); } session2.getTransaction().commit(); session2.close(); } // 测试Update与 Delete格式的HQL语对二级缓存的影响 // 会让二级缓存中相关的数据失效,下次使用这些数据时会重新到数据库中加载 @Test public void testUpdateTimestampCache() throws Exception { // ===================== 第1个Session Session session = SessionFactoryTools.getSession(); session.beginTransaction(); // 先获取 Employee employee = (Employee) session.get(Employee.class, 1); System.out.println(employee.getName()); // 再直接更新DB <span style="white-space:pre"> </span>session.createQuery("UPDATE Employee e SET e.name=? WHERE id=?")// .setParameter(0, "测试")// .setParameter(1, 1)// .executeUpdate();// 执行 // 再显示这个员工的名称 System.out.println(employee.getName()); session.getTransaction().commit(); session.close(); System.out.println("\n--------------------------------\n"); // ===================== 第2个Session Session session2 = SessionFactoryTools.getSession(); session2.beginTransaction(); Employee employee2 = (Employee) session2.get(Employee.class, 1); System.out.println(employee2.getName()); session2.getTransaction().commit(); session2.close(); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。