基于这段时间折腾redis遇到了各种问题,想着整理一下。本文主要介绍基于Spring+Mybatis以注解的形式整合Redis。废话少说,进入正题。
首先准备Redis,我下的是Windows版,下载后直接启动redis-server就行了,见下图:
一,先上jar包
二,创建实体类
1 package com.sl.user.vo; 2 3 import java.io.Serializable; 4 5 import com.fasterxml.jackson.databind.PropertyNamingStrategy; 6 import com.fasterxml.jackson.databind.annotation.JsonNaming; 7 import com.fasterxml.jackson.databind.annotation.JsonSerialize; 8 9 @JsonSerialize 10 @JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class) 11 public class UserVO implements Serializable{ 12 13 private static final long serialVersionUID = 1L; 14 15 private int id; 16 private String username; 17 private String password; 18 private int age; 19 20 public UserVO(){ 21 super(); 22 } 23 24 public UserVO(int id, String username, String password, int age) { 25 super(); 26 this.id = id; 27 this.username = username; 28 this.password = password; 29 this.age = age; 30 } 31 32 public int getId() { 33 return id; 34 } 35 36 public void setId(int id) { 37 this.id = id; 38 } 39 40 public String getUsername() { 41 return username; 42 } 43 44 public void setUsername(String username) { 45 this.username = username; 46 } 47 48 public String getPassword() { 49 return password; 50 } 51 52 public void setPassword(String password) { 53 this.password = password; 54 } 55 56 public int getAge() { 57 return age; 58 } 59 60 public void setAge(int age) { 61 this.age = age; 62 } 63 64 @Override 65 public String toString() { 66 return "UserVO [id=" + id + ", username=" + username + ", password=" 67 + password + ", age=" + age + "]"; 68 } 69 70 }
三,dao接口
1 package com.sl.user.dao; 2 3 import com.sl.user.vo.UserVO; 4 5 public interface UserDao { 6 7 public void addUser(UserVO user); 8 9 public void deleteUser(UserVO user); 10 11 public void updateUser(UserVO user); 12 13 public UserVO getUserById(int id); 14 15 public UserVO getUser(int id); 16 17 }
四,UserMapper
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > 3 <mapper namespace="com.sl.user.dao.UserDao" > 4 5 <resultMap id="userResult" type="User"> 6 <result column="id" property="id"/> 7 <result column="userame" property="userame"/> 8 <result column="password" property="password"/> 9 <result column="age" property="age"/> 10 </resultMap> 11 12 <insert id="addUser" parameterType="User"> 13 insert into t_user(username,password,age) values(#{username},#{password},#{age}) 14 </insert> 15 16 <update id="deleteUser" parameterType="User"> 17 delete * from t_user where id = #{id} 18 </update> 19 20 <update id="updateUser" parameterType="User"> 21 update t_user set 22 <if test="username != null and username != ''"> username = #{username},</if> 23 <if test="password != null and password != ''"> password = #{password},</if> 24 <if test="age != null and age != ''"> age = #{age}</if> 25 where 1=1 26 <if test="id != null and id != ''">and id = #{id}</if> 27 28 </update> 29 30 <select id="getUser" parameterType="int" resultType="User" > 31 select * from t_user where id = #{id} 32 </select> 33 34 <select id="getUserById" parameterType="int" resultType="java.lang.String" > 35 select username from t_user where id = #{id} 36 </select> 37 38 </mapper>
五,Service接口
1 package com.sl.user.service; 2 3 import com.sl.user.vo.UserVO; 4 5 public interface UserService { 6 7 public void addUser(UserVO user); 8 9 public void deleteUser(UserVO user); 10 11 public void updateUser(UserVO user); 12 13 public UserVO getUserById(int id); 14 15 public UserVO getUser(int id); 16 17 }
六,Service实现
1 package com.sl.user.service.impl; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.cache.annotation.CacheEvict; 5 import org.springframework.cache.annotation.Cacheable; 6 import org.springframework.stereotype.Service; 7 import org.springframework.transaction.annotation.Propagation; 8 import org.springframework.transaction.annotation.Transactional; 9 10 import com.sl.user.dao.UserDao; 11 import com.sl.user.service.UserService; 12 import com.sl.user.vo.UserVO; 13 14 @Service("userService") 15 @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 16 public class UserServiceImpl implements UserService{ 17 18 @Autowired 19 private UserDao userDao; 20 21 @Override 22 @CacheEvict(value="User",key="addUser",allEntries=true) 23 public void addUser(UserVO user) { 24 userDao.addUser(user); 25 } 26 27 @Override 28 @CacheEvict(value = {"getUser", "getUserById"}, allEntries = true) 29 public void deleteUser(UserVO user) { 30 userDao.deleteUser(user); 31 } 32 33 @Override 34 @CacheEvict(value = {"getUser", "getUserById"}, allEntries = true) 35 public void updateUser(UserVO user) { 36 userDao.updateUser(user); 37 } 38 39 @Override 40 @Cacheable(value="User",key="getUserById") 41 public UserVO getUserById(int id) { 42 return userDao.getUserById(id); 43 } 44 45 @Override 46 @Cacheable(value="User",key="'getUser'") 47 public UserVO getUser(int id) { 48 return userDao.getUser(id); 49 } 50 51 }
七,Ctrl层
1 package com.sl.user.web; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Controller; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.ResponseBody; 10 11 import com.sl.user.service.UserService; 12 import com.sl.user.vo.UserVO; 13 14 @Controller 15 @RequestMapping("/userCtrl") 16 public class UserCtrl { 17 18 @Autowired 19 private UserService userService; 20 21 @RequestMapping("/addUser") 22 public void addUser(UserVO user){ 23 userService.addUser(user); 24 } 25 26 @RequestMapping("/deleteUser") 27 public void deleteUser(UserVO user){ 28 userService.deleteUser(user); 29 } 30 31 @RequestMapping("/updateUser") 32 public void updateUser(UserVO user){ 33 userService.updateUser(user); 34 } 35 36 @ResponseBody 37 @RequestMapping("/getUserById") 38 public Map<String,Object> getUserById(UserVO user){ 39 Map<String,Object> map = new HashMap<String,Object>(); 40 map.put("msg",userService.getUserById(4)); 41 return map; 42 } 43 44 @ResponseBody 45 @RequestMapping("/getUser") 46 public Map<String,Object> getUser(UserVO vo){ 47 Map<String,Object> map = new HashMap<String,Object>(); 48 Object user = userService.getUser(4); 49 map.put("msg",user.toString()); 50 return map; 51 } 52 53 }
八,Redis关键类,用于CRUD操作
1 package com.sl.user.redis; 2 import java.io.ByteArrayInputStream; 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.ObjectInputStream; 6 import java.io.ObjectOutputStream; 7 8 import org.springframework.cache.Cache; 9 import org.springframework.cache.support.SimpleValueWrapper; 10 import org.springframework.dao.DataAccessException; 11 import org.springframework.data.redis.connection.RedisConnection; 12 import org.springframework.data.redis.core.RedisCallback; 13 import org.springframework.data.redis.core.RedisTemplate; 14 15 public class RedisUtil implements Cache{ 16 17 private RedisTemplate<String, Object> redisTemplate; 18 private String name; 19 public RedisTemplate<String, Object> getRedisTemplate() { 20 return redisTemplate; 21 } 22 23 public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { 24 this.redisTemplate = redisTemplate; 25 } 26 27 public void setName(String name) { 28 this.name = name; 29 } 30 31 @Override 32 public String getName() { 33 return this.name; 34 } 35 36 @Override 37 public Object getNativeCache() { 38 return this.redisTemplate; 39 } 40 41 /** 42 * 从缓存中获取key 43 */ 44 @Override 45 public ValueWrapper get(Object key) { 46 System.out.println("get key"); 47 final String keyf = key.toString(); 48 Object object = null; 49 object = redisTemplate.execute(new RedisCallback<Object>() { 50 public Object doInRedis(RedisConnection connection) 51 throws DataAccessException { 52 byte[] key = keyf.getBytes(); 53 byte[] value = connection.get(key); 54 if (value == null) { 55 return null; 56 } 57 return toObject(value); 58 } 59 }); 60 return (object != null ? new SimpleValueWrapper(object) : null); 61 } 62 63 /** 64 * 将一个新的key保存到缓存中 65 * 先拿到需要缓存key名称和对象,然后将其转成ByteArray 66 */ 67 @Override 68 public void put(Object key, Object value) { 69 System.out.println("put key"); 70 final String keyf = key.toString(); 71 final Object valuef = value; 72 final long liveTime = 86400; 73 redisTemplate.execute(new RedisCallback<Long>() { 74 public Long doInRedis(RedisConnection connection) 75 throws DataAccessException { 76 byte[] keyb = keyf.getBytes(); 77 byte[] valueb = toByteArray(valuef); 78 connection.set(keyb, valueb); 79 if (liveTime > 0) { 80 connection.expire(keyb, liveTime); 81 } 82 return 1L; 83 } 84 }); 85 } 86 87 private byte[] toByteArray(Object obj) { 88 byte[] bytes = null; 89 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 90 try { 91 ObjectOutputStream oos = new ObjectOutputStream(bos); 92 oos.writeObject(obj); 93 oos.flush(); 94 bytes = bos.toByteArray(); 95 oos.close(); 96 bos.close(); 97 }catch (IOException ex) { 98 ex.printStackTrace(); 99 } 100 return bytes; 101 } 102 103 private Object toObject(byte[] bytes) { 104 Object obj = null; 105 try { 106 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 107 ObjectInputStream ois = new ObjectInputStream(bis); 108 obj = ois.readObject(); 109 ois.close(); 110 bis.close(); 111 } catch (IOException ex) { 112 ex.printStackTrace(); 113 } catch (ClassNotFoundException ex) { 114 ex.printStackTrace(); 115 } 116 return obj; 117 } 118 119 /** 120 * 删除key 121 */ 122 @Override 123 public void evict(Object key) { 124 System.out.println("del key"); 125 final String keyf = key.toString(); 126 redisTemplate.execute(new RedisCallback<Long>() { 127 public Long doInRedis(RedisConnection connection) 128 throws DataAccessException { 129 return connection.del(keyf.getBytes()); 130 } 131 }); 132 } 133 134 /** 135 * 清空key 136 */ 137 @Override 138 public void clear() { 139 System.out.println("clear key"); 140 redisTemplate.execute(new RedisCallback<String>() { 141 public String doInRedis(RedisConnection connection) 142 throws DataAccessException { 143 connection.flushDb(); 144 return "ok"; 145 } 146 }); 147 } 148 149 @Override 150 public <T> T get(Object key, Class<T> type) { 151 return null; 152 } 153 154 @Override 155 public ValueWrapper putIfAbsent(Object key, Object value) { 156 return null; 157 } 158 159 }
九,Spring整合mybatis和redis配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xmlns:mvc="http://www.springframework.org/schema/mvc" 8 xmlns:aop="http://www.springframework.org/schema/aop" 9 xmlns:cache="http://www.springframework.org/schema/cache" 10 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 11 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 12 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 13 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 14 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 15 http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> 16 17 <!-- 扫描dao,service --> 18 <context:component-scan base-package="com.sl.user.service" /> 19 <context:component-scan base-package="com.sl.user.service.*" /> 20 <context:component-scan base-package="com.sl.user.redis" /> 21 <!-- 启用注解 --> 22 <context:annotation-config/> 23 <!-- 启动缓存注解 --> 24 <cache:annotation-driven/> 25 26 <!-- MyBatis start --> 27 <!-- 配置dataSource DriverManagerDataSource--> 28 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 29 <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> 30 <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property> 31 <property name="username" value="root"></property> 32 <property name="password" value="root"></property> 33 </bean> 34 35 <!-- MyBatis配置 SqlSessionFactoryBean --> 36 <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 37 <property name="dataSource" ref="dataSource"></property> 38 <property name="configLocation" value="classpath:config/mybatis.xml"></property> 39 <property name="mapperLocations" value="classpath:mapper/UserMapper.xml"></property> 40 </bean> 41 42 <!-- mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer 43 sqlSessionFactory 44 basePackage:指定sql映射文件/接口所在的包(自动扫描) --> 45 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 46 <property name="sqlSessionFactory" ref="sessionFactory"></property> 47 <property name="basePackage" value="com.sl.user.dao"></property> 48 </bean> 49 50 <!-- 事务管理 DataSourceTransactionManager--> 51 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 52 <property name="dataSource" ref="dataSource"></property> 53 </bean> 54 55 <!-- 使用声明式事务 transaction-manager:引用上面定义的事务管理器--> 56 <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven> 57 58 <!-- MyBatis end --> 59 60 <!-- 配置redis部分 start --> 61 62 <!-- 配置redis连接池 JedisPoolConfig--> 63 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> 64 <property name="maxIdle" value="300" /> 65 <property name="maxTotal" value="600" /> 66 </bean> 67 68 <!-- 配置CoonnectionFactory JedisConnectionFactory--> 69 <bean id="connFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> 70 <property name="hostName" value="127.0.0.1"></property> 71 <property name="port" value="6379"></property> 72 <property name="poolConfig" ref="poolConfig"></property> 73 </bean> 74 75 <!-- 配置redisTemplate StringRedisTemplate--> 76 <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> 77 <property name="connectionFactory" ref="connFactory"/> 78 </bean> 79 80 <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> 81 <property name="caches"> 82 <set> 83 <bean class="com.sl.user.redis.RedisUtil"> 84 <property name="redisTemplate" ref="redisTemplate" /> 85 <property name="name" value="User"/> 86 <!-- User名称要在类或方法的注解中使用 --> 87 </bean> 88 </set> 89 </property> 90 </bean> 91 92 </beans>
十,SpringMVC配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <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" 3 xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 6 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 7 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 9 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 10 11 <mvc:annotation-driven/> 12 <!-- 启用spring mvc 注解 --> 13 <context:annotation-config/> 14 <!-- 设置使用注解的类所在的jar包 --> 15 <context:component-scan base-package="com.sl.user.*"></context:component-scan> 16 17 <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 --> 18 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 19 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> 20 <property name="prefix" value="/views/"/> 21 <property name="suffix" value=".jsp"/> 22 </bean> 23 24 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> 25 <!-- JSON转换器 --> 26 <property name="messageConverters"> 27 <list> 28 <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 29 <property name="supportedMediaTypes"> 30 <list> 31 <value>application/json;charset=utf-8</value> 32 <value>text/json;charset=utf-8</value> 33 </list> 34 </property> 35 </bean> 36 </list> 37 </property> 38 </bean> 39 40 </beans>
十一,mybatis配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 4 <configuration> 5 6 <!-- 实体类,简称 -设置别名 --> 7 <typeAliases> 8 <typeAlias alias="User" type="com.sl.user.vo.UserVO" /> 9 </typeAliases> 10 11 </configuration>
十二,log4j
1 # Set root category priority to INFO and its only appender to CONSOLE. 2 log4j.rootCategory=DEBUG, CONSOLE 3 #log4j.rootCategory=INFO, CONSOLE, LOGFILE 4 5 # CONSOLE is set to be a ConsoleAppender using a PatternLayout. 6 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 7 log4j.appender.CONSOLE.Threshold=DEBUG 8 log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 9 log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p - %m%n 10 11 log4j.logger.java.sql.Connection=DEBUG 12 log4j.logger.java.sql.Statement=DEBUG 13 log4j.logger.java.sql.PreparedStatement=DEBUG 14 log4j.logger.java.sql.ResultSet=DEBUG
十三,web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="3.0" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 7 <display-name>TestRedis</display-name> 8 9 <context-param> 10 <param-name>contextConfigLocation</param-name> 11 <param-value> 12 classpath:config/applicationContext.xml 13 </param-value> 14 </context-param> 15 16 <context-param> 17 <param-name>log4jConfigLocation</param-name> 18 <param-value>classpath:config/log4j.properties</param-value> 19 </context-param> 20 <context-param> 21 <param-name>log4jRefreshInterval</param-name> 22 <param-value>60000</param-value> 23 </context-param> 24 25 <listener> 26 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 27 </listener> 28 <!-- 日志 --> 29 <listener> 30 <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 31 </listener> 32 33 <servlet> 34 <servlet-name>spring</servlet-name> 35 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 36 <init-param> 37 <param-name>contextConfigLocation</param-name> 38 <param-value>classpath:config/SpringMVC.xml</param-value> 39 </init-param> 40 <load-on-startup>1</load-on-startup> 41 </servlet> 42 <servlet-mapping> 43 <servlet-name>spring</servlet-name> 44 <url-pattern>*.do</url-pattern> 45 </servlet-mapping> 46 47 <!-- 解决中文乱码问题 --> 48 <filter> 49 <filter-name>characterEncoding</filter-name> 50 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 51 <init-param> 52 <param-name>encoding</param-name> 53 <param-value>UTF-8</param-value> 54 </init-param> 55 <init-param> 56 <param-name>forceEncoding</param-name> 57 <param-value>true</param-value> 58 </init-param> 59 </filter> 60 <filter-mapping> 61 <filter-name>characterEncoding</filter-name> 62 <url-pattern>*.do</url-pattern> 63 </filter-mapping> 64 65 66 <welcome-file-list> 67 <welcome-file>index.jsp</welcome-file> 68 </welcome-file-list> 69 </web-app>
十四,测试,已查询为例(getUser()方法),jsp测试页面整的比较丑就不贴出来了,自己写一个吧。。。
查询前:
执行第一次查询:
执行第二次查询操作:
上图可见,没有再执行sql,直接从redis中获取数据。
大功告成!!!!
在下初学,文中多有不足之处,还望多多指教。不喜勿喷。。。