一.Spring环境中配置Hibernate 和 ehcache
导入Hibernatejar:
其中ehcache-1.2.3.jar就是配置ehcache缓存需要的jar文件。
修改beans.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 配置自动扫描bean 包含注解 --> <context:component-scan base-package="com.zyy.service"/> <!-- 配置AOP --> <aop:aspectj-autoproxy/> <!-- 配置资源文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="${dataSource}" destroy-method="close"> <property name="driverClassName" value="${driverClassName}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> <!-- 连接池启动时的初始值 --> <property name="initialSize" value="${initialSize}"/> <!-- 连接池的最大值 --> <property name="maxActive" value="${maxActive}"/> <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --> <property name="maxIdle" value="${maxIdle}"/> <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --> <property name="minIdle" value="${minIdle}"/> </bean> <!-- 配置Hibernate二级缓存 --> <!--由Spring提供的LocalSessionFactoryBean管理Hibernate中SessionFactory中的session--> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingResources"> <list> <value>com/zyy/bean/Person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.hbm2ddl.auto=update hibernate.show_sql=false hibernate.format_sql=false <!-- 配置hibernate二级缓存 --> hibernate.cache.use_second_level_cache=true <!-- 不配置查询缓存 --> hibernate.cache.use_query_cache=false <!-- 配置缓存,这里配置的是EhCache缓存 --> hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider </value> </property> </bean> <!-- 配置事务 --> <!-- 这里使用Spring的bean和Spring对Hibernate支持的HibernateTransactionManager --> <!-- 属性注入的是Hibernate的二级缓存 --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 事务注解 --> <tx:annotation-driven transaction-manager="txManager"/> </beans>
这里是将JDBC的数据源 传入给Spring对Hibernate支持的HibernateTransactionManager
从而实现Spring中的Hibernate环境。
beans.xml需要的 jdbc.properties:
dataSource = org.apache.commons.dbcp.BasicDataSource driverClassName = org.gjt.mm.mysql.Driver url = jdbc:mysql://localhost:3306/ceshi_1?useUnicode=true&characterEncoding=UTF-8 username = root password = root initialSize = 1 maxActive = 500 maxIdle = 2 minIdle = 1
在类路径(src)下添加一个 ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?> <!-- diskStore指定缓存文件保存的路径 defaultCache节点为缺省的缓存策略 maxElementsInMemory 内存中最大允许存在的对象数量 eternal 设置缓存中的对象是否永远不过期 overflowToDisk 把溢出的对象存放到硬盘上 timeToIdleSeconds 指定缓存对象空闲多长时间就过期,过期的对象会被清除掉 timeToLiveSeconds 指定缓存对象总的存活时间 diskPersistent 当jvm结束是是否持久化对象 diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间 --> <ehcache> <diskStore path="D:\cache"/> <defaultCache maxElementsInMemory="1000" eternal="false" overflowToDisk="true" timeToIdleSeconds="120" timeToLiveSeconds="180" diskPersistent="false" diskExpiryThreadIntervalSeconds="60"/> <!-- 设置缓存的区域(可以多个),指定哪个表需要缓存 --> <cache name="com.zyy.service.Person" maxElementsInMemory="100" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" diskPersistent="false"/> </ehcache>
这时候 beans.xml 和 ehcache.xml 都需要一个 Hibernate表 和 其的配置 :
package com.zyy.bean; public class Person { private Integer id; private String name; public Person() { } public Person(String name) { this.name = name; } 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; } }
<?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.zyy.bean"> <class name="com.zyy.bean.Person"> <!-- usage说明了缓存的策略,region指定缓存的区域名 --> <cache usage="read-write" region="com.zyy.service.Person"/> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
由于导入的包中有log4j.jar,所以要在类路径(src)下添加一个 log4j.properties :
log4j.rootLogger=WARN, Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=(%r ms) [%t] %-5p: %c#%M %x: %m%n log4j.logger.com.genuitec.eclipse.sqlexplorer=DEBUG log4j.logger.org.apache=WARN log4j.logger.org.hibernate=WARN
以上,环境搭建结束。
二.测试环境
package com.zyy.service; import com.zyy.bean.Person; import java.util.List; /** * Created by CaMnter on 2014/8/20. */ public interface PersonService { /** * 保存对象 * * @param peroson */ public void save(Person peroson); /** * 更新对象 * * @param peroson */ public void update(Person peroson); /** * 删除单个对象 * * @param personId */ public void delete(Integer personId); /** * 取得单个对象 * * @return */ public Person getPerson(Integer personId); /** * 取得全部对象 * * @return */ public List<Person> getPersons(); }
package com.zyy.service.impl; import com.zyy.bean.Person; import com.zyy.service.PersonService; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service("personService") @Transactional public class PersonServiceBean implements PersonService { /** * 这里的sessionFactory 配置的class * * 配置的class是org.springframework.orm.hibernate3.LocalSessionFactoryBean * * 由Spring提供的LocalSessionFactoryBean管理Hibernate中SessionFactory中的session */ //将Autowired转换为按 名称匹配 @Autowired @Qualifier("sessionFactory") private SessionFactory sessionFactory; public void save(Person peroson) { /** * this.sessionFactory.getCurrentSession() 得到当前的session * * persist()保存实体 和 save()一样 */ this.sessionFactory.getCurrentSession().persist(peroson); } public void update(Person peroson) { /** * this.sessionFactory.getCurrentSession() 得到当前的session * * merge() 和 update()方法一样 */ this.sessionFactory.getCurrentSession().merge(peroson); } public void delete(Integer personId) { /** * this.sessionFactory.getCurrentSession() 得到当前的session * * 通过load(表.class, personId)方法 读取 Person * * 然后再用Person 执行delete(Object)方法 */ this.sessionFactory.getCurrentSession().delete( this.sessionFactory.getCurrentSession().load(Person.class, personId)); } @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true) public Person getPerson(Integer personId) { /** * this.sessionFactory.getCurrentSession() 得到当前的session * * 通过load(表.class, personId)方法 读取 Person * * 然后再用Person 执行get(Object)方法 */ return (Person) this.sessionFactory.getCurrentSession().get(Person.class, personId); } @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true) public List<Person> getPersons() { //from 类名 不是from 数据库里的表名 //noinspection JpaQlInspection String hql = "from Person" ; /** * 这里比 Spring+JDBC 返回一组list数据方便多了 */ return this.sessionFactory.getCurrentSession().createQuery(hql).list(); } }
junit4.4测试类:
package test.com.zyy.service.impl; import com.zyy.bean.Person; import com.zyy.service.PersonService; import org.junit.Test; import org.junit.Before; import org.junit.After; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * PersonServiceBean Tester. * * @author <Authors name> * @version 1.0 */ public class PersonServiceBeanTest { private PersonService personService; @Before public void before() throws Exception { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); this.personService = (PersonService) applicationContext.getBean("personService"); } @After public void after() throws Exception { } /** * Method: save(Person peroson) */ @Test public void testSave() throws Exception { this.personService.save(new Person("CaMnter_SSH_save")); for (int i = 0; i < 15; i++) { this.personService.save(new Person("CaMnter_SSH_save_" + i)); } } /** * Method: update(Person peroson) */ @Test public void testUpdate() throws Exception { Person person = new Person("CaMnter_SSH_update"); person.setId(4); this.personService.update(person); } /** * Method: delete(Integer personId) */ @Test public void testDelete() throws Exception { this.personService.delete(6); } /** * Method: getPerson(Integer personId) */ @Test public void testGetPerson() throws Exception { Person person = this.personService.getPerson(7); System.out.println("id: " + person.getId() + " name: " + person.getName()); } /** * Method: getPersons() */ @Test public void testGetPersons() throws Exception { for (Person person : this.personService.getPersons()) { System.out.println("id: " + person.getId() + " name: " + person.getName()); } } @Test public void testCache() { Person person = this.personService.getPerson(7); System.out.println("id: " + person.getId() + " name: " + person.getName()); try { Thread.sleep(1000 * 7); System.out.println("请关闭Mysql数据库"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("第二次获取"); person = this.personService.getPerson(7); System.out.println("id: " + person.getId() + " name: " + person.getName()); } }
这里,我就附上一个测试取得全部person的的结果:
注意:测试cache的时候,点击执行testCach()单元方法后,会立刻看到一条数据输出,然
后睡眠了七秒,再读取。如果在睡眠的七秒内,关闭了数据库,后还能再读取,证明cache配置
成功;如果有异常则配置失败。
可以发现D:/cache文件夹下有内容: