spring+springmvc+mybatis+redis实现缓存
2017-05-03 09:33 甘雨路 阅读(6433) 评论(1) 编辑 收藏 举报先搭建好redis环境
需要的jar如下:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/cache_test
jdbc.username=root
jdbc.password=
redis.host=127.0.0.1
redis.port=6379
redis.maxIdle=2000
redis.maxActive=60000
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=100000
defaultCacheExpireTime=60
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置mybatis的缓存,延迟加载等相关属性 --> <settings> <!-- 是否开启全局缓存 --> <setting name="cacheEnabled" value="true"/> <!-- 查询时,关闭关联对象即时加载以提高性能 --> <setting name="lazyLoadingEnabled" value="false"/> <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 --> <setting name="multipleResultSetsEnabled" value="true"/> <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 --> <setting name="aggressiveLazyLoading" value="true"/> </settings> </configuration>
<?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:lang="http://www.springframework.org/schema/lang" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- 包扫描 --> <context:component-scan base-package="sysone.zr.com" /> <!-- 引入外部文件 --> <context:property-placeholder location="/WEB-INF/config/jdbc.properties,/WEB-INF/config/redis.properties"/> <!-- 开启动态代理 --> <aop:aspectj-autoproxy/> <!-- 事务属性配置 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- 事务传播属性 --> <tx:attributes> <!-- 所有已get、query、select开头的方法都是只读 --> <tx:method name="get*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="select*" read-only="true"/> <!-- 其它的所有方法支持事务设置的属性(异常回滚) --> <tx:method name="*" rollback-for="java.lang.Throwing" /> </tx:attributes> </tx:advice> <aop:config> <!-- 配置切点 --> <aop:pointcut id="fooServiceOperation" expression="execution(* sysone.zr.com.service.sysone.zr.com.service.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/> </aop:config> <!-- 数据源配置 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 配置数据源管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- mybatis配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="/WEB-INF/config/mybatis-config.xml"/> <property name="typeAliasesPackage" value="sysone.zr.com.mapper.model"/> <property name="mapperLocations"> <list> <value>classpath:sysone/zr/com/mapper/xml/*Mapper.xml</value> </list> </property> </bean> <!-- mybatis 扫描 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="sysone.zr.com.mapper.imapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> <!-- 配置redis 单机版 --> <!-- redis数据源 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大空闲数 --> <property name="maxIdle" value="${redis.maxIdle}" /> <!-- 最大空闲数 --> <property name="maxTotal" value="${redis.maxActive}" /> <!-- 最大等待时间 --> <property name="maxWaitMillis" value="${redis.maxWait}" /> <!-- 返回连接时,检测连接是否成功 --> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- Spring-redis连接池管理工厂 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <!-- IP地址 --> <property name="hostName" value="${redis.host}" /> <!-- 端口号 --> <property name="port" value="${redis.port}" /> <!-- 超时时间 --> <property name="timeout" value="${redis.timeout}" /> <property name="poolConfig" ref="poolConfig" /> </bean> <!-- redis 集群 --> <!-- <bean id="redisClient" class="redis.clients.jedis.JedisCluster"> <constructor-arg name="nodes"> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.10.105"></constructor-arg> <constructor-arg name="port" value="7002"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.10.77"></constructor-arg> <constructor-arg name="port" value="7002"></constructor-arg> </bean> </constructor-arg> </bean> --> <!-- redis模板类,提供了对缓存的增删改查 --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> </property> </bean> <!-- StrRedisTemplate --> <bean id="strRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> </bean> <!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 --> <bean id="redisCacheTransfer" class="sysone.zr.com.utils.RedisCacheTransfer"> <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/> </bean> <!-- //End 单机版Redis集成 --> <!-- Redis缓存管理对象 --> <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg index="0" ref="redisTemplate" /> </bean> <!-- 开启Spring缓存 --> <cache:annotation-driven cache-manager="cacheManager"/> </beans>
<?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:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" > <!-- 包扫描 --> <context:component-scan base-package="sysone.zr.com" /> <!-- 开启Springmvc注解驱动 --> <mvc:annotation-driven /> <!-- SpringMVC视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 拦截器 --> <!-- <bean id="urlhandler" class="sysone.zr.com.interception.URLHandler"></bean> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/lf/online/**"/> <ref bean="urlhandler"/> </mvc:interceptor> </mvc:interceptors> --> </beans>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <!-- 配置springmvc核心 Servlet--> <servlet> <servlet-name>pringmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置文件加载的路径 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>pringmvc</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <!-- END 配置springmvc核心 Servlet--> <!-- spring 路径的配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/spring.xml</param-value> </context-param> <!--END spring 路径的配置 --> <!-- 配置spring监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--END 配置spring监听器 --> </web-app>
package sysone.zr.com.controller; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import sysone.zr.com.mapper.model.Person; import sysone.zr.com.service.PersonService; @Controller public class TestController { @Resource private PersonService personService; @RequestMapping("/person.htm") public void getPersonInfo(){ List<Person> persons = personService.getAllPerson(); if (persons!=null) { for (Person person : persons) { System.out.println("person:"+person); } } } }
package sysone.zr.com.mapper.imapper; import java.util.List; import sysone.zr.com.mapper.model.Person; public interface PersonMapper { /** * 获取所有person的信息 * @return */ List<Person> getAllPerson(); }
package sysone.zr.com.mapper.model; import java.io.Serializable; public class Person implements Serializable { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person() { super(); } public Person(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="sysone.zr.com.mapper.imapper.PersonMapper"> <!-- 支持缓存配置 --> <cache type="sysone.zr.com.utils.RedisCache" /> <resultMap type="sysone.zr.com.mapper.model.Person" id="baseMap"> <id property="id" column="id" /> <result property="name" column="name"/> <result property="age" column="age"/> </resultMap> <select id="getAllPerson" resultMap="baseMap"> SELECT id,name,age FROM PERSON </select> </mapper>
package sysone.zr.com.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import sysone.zr.com.mapper.imapper.PersonMapper; import sysone.zr.com.mapper.model.Person; import sysone.zr.com.service.PersonService; @Service public class PersonServerImpl implements PersonService { @Resource private PersonMapper mapper; @Override public List<Person> getAllPerson() { System.out.println("===== 获取person信息 ====="); return mapper.getAllPerson(); } }
package sysone.zr.com.service; import java.util.List; import sysone.zr.com.mapper.model.Person; public interface PersonService { /** * 获取所有的person信息 * @return */ List<Person> getAllPerson(); }
package sysone.zr.com.utils; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.ibatis.cache.Cache; import org.springframework.data.redis.connection.jedis.JedisConnection; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; public class RedisCache implements Cache { private static JedisConnectionFactory jedisConnectionFactory; private final String id; private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public RedisCache(final String id){ if (id == null) { throw new IllegalArgumentException("cache instances require an ID"); } this.id = id; } @Override public void clear() { JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); connection.flushDb(); connection.flushAll(); } catch (Exception e) { e.printStackTrace(); }finally{ if (connection != null) { connection.close(); } } } @Override public String getId() { return this.id; } @Override public Object getObject(Object key) { System.out.println("--------------------------------key:"+key); Object result = null; JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); result = serializer.deserialize(connection.get(serializer.serialize(key))); } catch (Exception e) { e.printStackTrace(); }finally{ if (connection != null) { connection.close(); } } return result; } @Override public ReadWriteLock getReadWriteLock() { return this.readWriteLock; } @Override public int getSize() { int result = 0; JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); result = Integer.valueOf(connection.dbSize().toString()); } catch (Exception e) { e.printStackTrace(); }finally{ if (connection != null) { connection.close(); } } return result; } @Override public void putObject(Object key, Object value) { System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>key:"+key); JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); System.out.println("**"+serializer.serialize(key)); connection.set(serializer.serialize(key), serializer.serialize(value)); } catch (Exception e) { e.printStackTrace(); }finally{ if (connection != null) { connection.close(); } } } @Override public Object removeObject(Object key) { JedisConnection connection = null; Object result = null; try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); result = connection.expireAt(serializer.serialize(key), 0); } catch (Exception e) { e.printStackTrace(); }finally{ if (connection != null) { connection.close(); } } return result; } public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) { RedisCache.jedisConnectionFactory = jedisConnectionFactory; } }
package sysone.zr.com.utils; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; public class RedisCacheTransfer { public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) { RedisCache.setJedisConnectionFactory(jedisConnectionFactory); } }