基於這段時間折騰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中獲取數據。
大功告成!!!!
在下初學,文中多有不足之處,還望多多指教。不喜勿噴。