9.Spring + Hibernate + ehcache(二级缓存






一.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文件夹下有内容:






























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值