标签:
一级缓存主要作用是管理对象。不管是一级缓存还是二级缓存,都需要根据OID获取对象才有效。
package test.hibernate.hbmSecondCache; import java.util.HashSet; import java.util.Set; public class Department { private Integer id; private String name; private Set<Employee> employees = new HashSet<Employee>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Employee> getEmployees() { return employees; } public void setEmployees(Set<Employee> employees) { this.employees = employees; } @Override public String toString() { // TODO Auto-generated method stub return "[employee:id=" + id + ",name=" + name + "]"; } }
package test.hibernate.hbmSecondCache; public class Employee { private Integer id; private String name; private Department department = new Department(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public String toString() { // TODO Auto-generated method stub return "[Employee:id=" + id + ",name=" + name + "]"; } }
<?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="test.hibernate.hbmSecondCache"> <class name="Department" table="department"> <id name="id" type="integer" column="id"> <generator class="native" /> </id> <property name="name" /> <set name="employees" inverse="false" cascade="save-update" lazy="extra"> <key column="departmentId"></key> <one-to-many class="Employee" /> </set> </class> </hibernate-mapping>
<?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="test.hibernate.hbmSecondCache"> <class name="Employee" table="employee"> <!-- 指定当前类使用二级缓存 --> <!-- <cache usage="read-write" /> --> <id name="id" type="integer" column="id"> <generator class="native" /> </id> <property name="name" /> <many-to-one name="department" class="Department" column="departmentId"></many-to-one> </class> </hibernate-mapping>
<!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="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate_2015</property> <!-- 可简写为<property name="connection.url">jdbc:mysql:///hibernate_2015</property> --> <property name="connection.username">root</property> <property name="connection.password">686175</property> <!-- 显示生成的sql语句,不写的话默认是false --> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <!-- 设置事务隔离级别 --> <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">10</property> <!-- 设定数据库连接的过期时间,以秒为单位,如果连接池中的某个 数据库连接处于空闲状态的时间超过timeout时间,就会从连接池中清除 --> <property name="c3p0.timeout">100</property> <!-- 以秒为单位,每idle_test_period秒检查所有连接池中的空闲连接 --> <property name="c3p0.idle_test_period">2000</property> <!-- 指定缓存提供商 --> <!-- <property name="cache.provider_class"> org.hibernate.cache.HashtableCacheProvider </property> --> <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <!-- 指定开启查询缓存 --> <property name="cache.use_query_cache">true</property> <!-- 指定使用二级缓存的实体类 --> <class-cache usage="read-only" class="test.hibernate.hbmSecondCache.Employee" /> <class-cache usage="read-write" class="test.hibernate.hbmSecondCache.Department" /> <!-- 表示Department类里的集合要进行缓存 --> <collection-cache usage="read-write" collection="test.hibernate.hbmSecondCache.Department.employees" /> </session-factory> </hibernate-configuration>懒加载的类(Department)中的集合(Employee)要进行懒加载也需要另外进行设置,同时Employee类也要打开。
package test.hibernate.hbmSecondCache; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.junit.Test; public class App { private static SessionFactory sessionFactory = new Configuration()// .configure()// .addClass(Department.class)// 添加Hibernate实体类(加载对应的映射文件) .addClass(Employee.class)// .buildSessionFactory(); // 获取到部门关联的员工 @Test public void testSessionCache1() throws Exception { // ----------------测试第二个Session------------------- Session session1 = sessionFactory.openSession(); session1.beginTransaction(); Employee employee1 = (Employee) session1.get(Employee.class, 1); session1.getTransaction().commit(); session1.close(); // ----------------测试第二个Session------------------- Session session2 = sessionFactory.openSession(); session2.beginTransaction(); Employee employee2 = (Employee) session2.get(Employee.class, 1); // employee2.setName("力普"); session2.getTransaction().commit(); session2.close(); } @Test public void testSessionCache2() throws Exception { // ----------------测试第二个Session------------------- Session session1 = sessionFactory.openSession(); session1.beginTransaction(); Department department1 = (Department) session1.get(Department.class, 1); System.out.println(department1.getEmployees()); session1.getTransaction().commit(); session1.close(); // ----------------测试第二个Session------------------- Session session2 = sessionFactory.openSession(); session2.beginTransaction(); Department department2 = (Department) session2.get(Department.class, 1); // department2.setName("研发部"); System.out.println(department2.getEmployees()); session2.getTransaction().commit(); session2.close(); } // Query.list()默认不会使用二级缓存 @Test public void testQueryCache() throws Exception { // ----------------------------------- Session session1 = sessionFactory.openSession(); session1.beginTransaction(); List<Employee> list = session1.createQuery( "From Employee e WHERE e.id<5").list(); System.out.println(list); session1.getTransaction().commit(); session1.close(); // --------------------------------------------------- Session session2 = sessionFactory.openSession(); session2.beginTransaction(); List<Employee> list2 = session2.createQuery( "From Employee e WHERE e.id<5").list(); System.out.println(list2); session2.getTransaction().commit(); session2.close(); } /* * 在使用HQL方式查询时,如果用iterator()方法,就会使用缓存。 这个方法先查询所有符合条件的id集合,再一个一个地按id查找数据。 * 但这个方法会有n+1次查询的问题,提高性能有限,不太常用。 */ @Test public void testQueryCache2() throws Exception { // ----------------------------------- Session session1 = sessionFactory.openSession(); session1.beginTransaction(); Iterator<Employee> iterator1 = session1.createQuery( "FROM Employee WHERE id <5").iterate(); while (iterator1.hasNext()) { System.out.println(iterator1.next()); } session1.getTransaction().commit(); session1.close(); // --------------------------------------------------- Session session2 = sessionFactory.openSession(); session2.beginTransaction(); Iterator<Employee> iterator2 = session2.createQuery( "FROM Employee WHERE id <5").iterate(); while (iterator2.hasNext()) { System.out.println(iterator2.next()); } session2.getTransaction().commit(); session2.close(); } // 使用二级缓存需在主配置文件开启查询缓存 @Test public void testQueryCache3() throws Exception { // ----------------------------------- Session session1 = sessionFactory.openSession(); session1.beginTransaction(); List<Employee> list = session1 .createQuery("From Employee e WHERE e.id<5")// .setCacheable(true)// .list(); System.out.println(list); session1.getTransaction().commit(); session1.close(); // --------------------------------------------------- Session session2 = sessionFactory.openSession(); session2.beginTransaction(); // 两次查询条件需相同二级缓存才有用 List<Employee> list2 = session2.createQuery(// "From Employee e WHERE e.id<5")// .setCacheable(true)// .list(); System.out.println(list2); session2.getTransaction().commit(); session2.close(); } @Test public void testUpdateTimeStampCache() throws Exception { // ----------------------------------- Session session1 = sessionFactory.openSession(); session1.beginTransaction(); List<Employee> list = session1 .createQuery("From Employee e WHERE e.id<2")// .setCacheable(true)// .list(); session1.createQuery("UPDATE Employee SET name=? WHERE id=?") .setParameter(0, "漫画")// .setParameter(1, 3)// .executeUpdate(); System.out.println(list); session1.getTransaction().commit(); session1.close(); // --------------------------------------------- System.out.println("============================="); Session session2 = sessionFactory.openSession(); session2.beginTransaction(); // 两次查询条件需相同二级缓存才有用 List<Employee> list2 = session2.createQuery(// "From Employee e WHERE e.id<7")// .setCacheable(true)// .list();// 打断点->debug,可以看到E:/cache/下缓存生成的文件 // 此时employees[3]已失效,会输出session1更新后的结果 System.out.println(list2); session2.getTransaction().commit(); session2.close(); } }使用EnCache缓存需配置ehcache.xml。导入一些jar包:ehcache-1.5.0.jar、backport-util-concurrent.jar、commons-logging-1.0.4.jar
<ehcache> <!--缓存文件存放的位置--> <diskStore path="E:/cache/"/> <!--Default Cache configuration. These will applied to caches programmatically created through the CacheManager. The following attributes are required for defaultCache: maxInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. --> <defaultCache maxElementsInMemory="1" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> </ehcache>
testSessionCache
testQueryCache2
testUpdateTimeStampCache
使用EhCache在D:/cache/生成的缓存文件
版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载,请注明出处:http://blog.csdn.net/lindonglian
标签:
原文地址:http://blog.csdn.net/lindonglian/article/details/46991115