作者:yxl_num
感谢原作者!!
前两天写过 springMVC+memcached 的整合,我从这个基础上改造一下,把redis和springmvc整合到一起。
和memcached一样,redis也有java专用的客户端,官网推荐使用的是:jedis。
看了一部分资料,大家推荐使用 spring-data-redis (spring在jedis的基础上又包装了一层),但是实际中感觉写起来有点麻烦,不如原生态的jedis好用。
所以我利用spring的构造注入做了一个springmvc整合jedis的例子。
先了解下redis吧,这些资料袋都是从网上看到的:
Redis使用c语言编写,面向“键/值”对类型数据的分布式NoSql数据库系统。
目前提供五中数据类型
string(字符串)
list(链表)
Hash(哈希)
set(集合)
zset(sorted set 有序集合),有2中编码类型:ziplist,skiplist,当zset中数据较多时,将会被重构为skiplist。
默认端口6379
redis-server.exe:服务端
redis-check-dump.exe:本地数据库检查
redis-check-aof.exe:更新日志检查
redis-benchmark.exe:性能测试,用以模拟同时由N个客户端发送M个 SETs/GETs 查询.
redis-cli.exe: 这个是客户端,服务端开启后,客户端就可以输入各种命令测试了
先写一个Test类,测一下redis的基本数据类型和jedis的一些常用方法。以下的测试方法也都是从网上看到的,只不过为了验证是否准确以及jar包版本的问题,我自己亲自敲了一遍。
注意jedis是redis的一个客户端,是个jar包,不要搞混了……
public class Test { public static void main(String[] args) {/**************************测试Redis的数据类型**************************/ /** * list */ /** * set 无须唯一 */ /** * zset(sorted set 有序集合) * 有2中编码类型:ziplist,skiplist,当zset中数据较多时,将会被重构为skiplist */ /** * Hash *//**************************事务控制**************************/ /** * 事务方式(Transactions) * 他主要目的是保障,一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 * * 我们调用jedis.watch(…)方法来监控key,如果调用后key值发生变化,则整个事务会执行失败。 * 另外,事务中某个操作失败,并不会回滚其他操作。这一点需要注意。 * 还有,我们可以使用discard()方法来取消事务。 */ /**************************管道**************************/ /** * 管道(Pipelining) * 有时,我们需要采用异步方式,一次发送多个指令,不同步等待其返回结果。 * 这样可以取得非常好的执行效率。这就是管道 *//**************************管道中调用事务**************************/ /** * 管道中调用事务 * 在用法上看,管道中包含了事务 *//**************************分布式直连同步调用**************************/ /** * 分布式直连同步调用 * 线程不安全的,不建议在线程池中使用直连 *//**************************分布式直连同步调用**************************/ /** * 分布式直连异步调用 * 线程不安全的,不建议在线程池中使用直连 */ /**************************分布式连接池同步调用**************************/ /** * 同步方式 *//**************************分布式连接池异步调用**************************/ /** * 异步方式 */ /**************************其他**************************/ /** * 清空所有 */ /** * 销毁链接 */}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
开始贴代码了,springMVC整合jedis
web.xml
<?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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SpringMVC-Redis</display-name> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/applicationContext*.xml</param-value> </context-param> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/spring-servlet-config.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>SpringMVC-Redis-Encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>SpringMVC-Redis-Encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery/jquery-1.8.0.min.js"></script><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>index 2</title></head><body> <div><font color="red" size="10px">${returnMsg}</font></div> <form action="${pageContext.request.contextPath }/TestRequest/test" method="post" name="loginForm" id="loginForm"> <div> 用户名:<input class="username" type="text" id="username" name="username" value=‘‘/> </div> <div > 密码:<input class="password" type="password" id="password" name="password" value=""/> </div> <div><input type="button" value="submit" onclick="login()" /></div> </form> <script type="text/javascript"> function login(){ var username = $("#username").val(); var password = $("#password").val(); $("#loginForm").submit(); } document.onkeydown=function(event){ e = event ? event :(window.event ? window.event : null); if(e.keyCode==13){ login(); } } </script></body></html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
spring-servlet-config.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <mvc:annotation-driven /> <context:component-scan base-package="com.test" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" /> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" /> <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" /> </context:component-scan> <mvc:resources mapping="/js/**" location="/js/" /> <mvc:resources mapping="/image/**" location="/image/" /> <mvc:resources mapping="/css/**" location="/css/" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix" value="/pages/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">error/403</prop> </props> </property> </bean> </beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
先把这些贴上来是因为这些文件内容都和上篇博文”springMVC+memcached “的一模一样
applicationContext.xml
利用spring的构造注入,把集群参数传入RedisInitBean中,并且在项目启动的时候加载RedisInitBean的有参构造方法
<?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-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <bean id="RedisInitBean" class="com.test.test.RedisInitBean" > <constructor-arg index="0" type="List"> <list> <value>127.0.0.1:6379</value> <value>192.168.3.27:6380</value> </list> </constructor-arg> <constructor-arg index="1" type="long"> <value>1000</value> </constructor-arg> <constructor-arg index="2" type="int"> <value>200</value> </constructor-arg> <constructor-arg index="3" type="Boolean"> <value>true</value> </constructor-arg> </bean></beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
RedisInitBean.java
这里面要说一下,使用的是 分布式连接池 异步调用!
package com.test.test;import java.util.Arrays;import java.util.List;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.JedisShardInfo;import redis.clients.jedis.ShardedJedis;import redis.clients.jedis.ShardedJedisPool;public class RedisInitBean { private List Host; private long maxWaitMillis; private int MaxIdle; private Boolean testOnBorrow; private static List<JedisShardInfo> shards ; private static ShardedJedisPool pool; private static ShardedJedis jedis; public RedisInitBean(List host, long maxWaitMillis, int maxIdle, Boolean testOnBorrow) { super(); Host = host; this.maxWaitMillis = maxWaitMillis; MaxIdle = maxIdle; this.testOnBorrow = testOnBorrow; if(host.size()!=0){ for (int i = 0; i < host.size(); i++) { String h[] = ((String) host.get(i)).split(":"); shards = Arrays.asList(new JedisShardInfo(h[0].trim(),Integer.parseInt(h[1].trim()))); System.out.println(shards); } }else{ System.out.println("请检查Redis配置,host项为必填项!格式[IP:PORT]"); } pool = new ShardedJedisPool(new JedisPoolConfig(), shards); jedis = pool.getResource(); } public synchronized ShardedJedis getSingletonInstance(){ return jedis; } public synchronized static void returnResource(){ pool.returnResource(jedis); } public synchronized static void destroy(){ pool.destroy(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
TestRequest.java
刚才我们写的index.jsp中,提交了表单后浏览器会发起请求,spring拦截请求后会找到注解匹配的类中的方法,TestRequest就是了。
package com.test.webimport java.util.Listimport javax.servlet.http.HttpSessionimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.stereotype.Controllerimport org.springframework.web.bind.annotation.RequestMappingimport org.springframework.web.bind.annotation.RequestParamimport org.springframework.web.servlet.ModelAndViewimport redis.clients.jedis.ShardedJedisimport redis.clients.jedis.ShardedJedisPipelineimport com.test.test.RedisInitBean@Controller@RequestMapping("/TestRequest")public class TestRequest { @Autowired private RedisInitBean rib @RequestMapping("/test") public ModelAndView test(@RequestParam(value = "username") final String userid, @RequestParam(value = "password") final String passwd, HttpSession session){ ModelAndView m = new ModelAndView() m.setViewName("../index") ShardedJedis jedis = rib.getSingletonInstance() ShardedJedisPipeline pipeline = jedis.pipelined() long start = System.currentTimeMillis() for (int i = 0 pipeline.set("zhenbn" + i, "n" + i) } List<Object> results = pipeline.syncAndReturnAll() long end = System.currentTimeMillis() rib.returnResource() rib.destroy() System.out.println("分布式连接池异步调用耗时: " + ((end - start)/1000.0) + " 秒") try { Thread.sleep(5000) } catch (InterruptedException e) { e.printStackTrace() } System.out.println("返回结果:"+results) m.addObject("returnMsg","么么哒!") return m }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
存完之后,我们可以取一下试试,看看到底有没有存进去。
![这里写图片描述](http://img.blog.csdn.net/20160919161403767)
看,取到了吧~
使用jedis的时候要注意配合commons-pool2.jar使用,否则会报错的。
原因是 JedisPoolConfig extends GenericObjectPoolConfig,
![这里写图片描述](http://img.blog.csdn.net/20160919161423330)
而GenericObjectPoolConfig则是:
![这里写图片描述](http://img.blog.csdn.net/20160919161435471)
BaseObjectPoolConfig则是:
![这里写图片描述](http://img.blog.csdn.net/20160919161450049)
jar包下载:http://pan.baidu.com/s/1jGBVJds