前两天写过 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) {
// Jedis js = new Jedis("127.0.0.1", 6379); // js.set("key001", "redis001");
// String val = js.get("key001");
// System.out.println(val);
// js.del("key001"); /**************************测试Redis的数据类型**************************/ /**
* list
*/
// js.rpush("list1", "aaaaaaaaaaaaaaaaaaaaaa");
// js.rpush("list1", "bbbbbbbbbbbbbbbbbbbbbb");
// js.rpush("list1", "ccccccccccccccccccccc");
// js.rpush("list1", "dddddddddddddd");
// List<String> vals = js.lrange("list1", 0, -1);
// for (int i = 0; i < vals.size(); i++) {
// System.out.println(vals.get(i));
// } /**
* set 无须唯一
*/
// js.sadd("s1", "顺序3");
// js.sadd("s1", "a");
// js.sadd("s1", "b");
// js.sadd("s1", "1");
// js.sadd("s1", "蛤蛤蛤");
// js.sadd("s1", "2");
// js.sadd("s1", "so waht?");
// js.sadd("s1", "%^");
// js.sadd("s1", "顺序1");
// js.sadd("s1", "乱码吗?");
// js.sadd("s1", "顺序2");
// Set<String> s = js.smembers("s1");
// for (String string : s) {
// System.out.println(s);
// }
// js.srem("s1", "蛤蛤蛤"); /**
* zset(sorted set 有序集合)
* 有2中编码类型:ziplist,skiplist,当zset中数据较多时,将会被重构为skiplist
*/
// js.zadd("zs", 92, "张三1");
// js.zadd("zs", 93, "张三7");
// js.zadd("zs", 94, "张三5");
// js.zadd("zs", 87, "张三9");
// js.zadd("zs", 66, "张三");
// js.zadd("zs", 19, "张三0");
// Set<String> sets = js.zrange("zs", 0, -1);
// for (String string : sets) {
// System.out.println(sets);
// } /**
* Hash
*/
// Map m = new HashMap();
// m.put("1", "t");
// m.put("2", "ttt");
// m.put("username", "老王");
// m.put("password", "123456");
// m.put("age", "79");
// m.put("sex", "man");
// js.hmset("m", m);
// List<String> v = js.hmget("m", new String[]{"username","age"});
// List<String> v1 = js.hmget("m", "sex");
// System.out.println(v);
// System.out.println(v1);
// js.hdel("m", "username");//删除map中的某一个键的键值对 /**************************事务控制**************************/ /**
* 事务方式(Transactions)
* 他主要目的是保障,一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。
*
* 我们调用jedis.watch(…)方法来监控key,如果调用后key值发生变化,则整个事务会执行失败。
* 另外,事务中某个操作失败,并不会回滚其他操作。这一点需要注意。
* 还有,我们可以使用discard()方法来取消事务。
*/
// Jedis js1 = new Jedis("127.0.0.1", 6379);
// long s = System.currentTimeMillis();
// Transaction tx = js1.multi();
// for (int i = 0; i < 99999; i++) {
// tx.set("keyttt"+i, "valttt"+i);
// }
// List<Object> res= tx.exec();
// long e = System.currentTimeMillis();
// System.out.println((e-s)/1000.0+"秒");
//System.out.println(res);
// js1.disconnect(); /**************************管道**************************/
/**
* 管道(Pipelining)
* 有时,我们需要采用异步方式,一次发送多个指令,不同步等待其返回结果。
* 这样可以取得非常好的执行效率。这就是管道
*/
// Jedis js2 = new Jedis("127.0.0.1", 6379);
// long s = System.currentTimeMillis();
// Pipeline pe = js2.pipelined();
// for (int i = 0; i < 9999; i++) {
// pe.set("keya"+i, "valuea"+i);
// }
// List<Object> l = pe.syncAndReturnAll();
// long e = System.currentTimeMillis();
// System.out.println((e-s)/1000.0+"秒");
// js2.disconnect(); /**************************管道中调用事务**************************/
/**
* 管道中调用事务
* 在用法上看,管道中包含了事务
*/ // Jedis js3 = new Jedis("127.0.0.1", 6379);
// long s = System.currentTimeMillis();
// Pipeline pe = js3.pipelined();
// pe.multi();
// for (int i = 0; i < 9999; i++) {
// pe.set("keybb"+i, "valuebb"+i);
// }
// pe.exec();
// List<Object> l = pe.syncAndReturnAll();
// long e = System.currentTimeMillis();
// System.out.println((e-s)/1000.0+"秒");
// js3.disconnect(); /**************************分布式直连同步调用**************************/
/**
* 分布式直连同步调用
* 线程不安全的,不建议在线程池中使用直连
*/
// List<JedisShardInfo> shards = Arrays.asList(
// new JedisShardInfo("localhost",6379),
// new JedisShardInfo("localhost",6380));
// ShardedJedis sharding = new ShardedJedis(shards);
// long start = System.currentTimeMillis();
// for (int i = 0; i < 100000; i++) {
// String result = sharding.set("sn" + i, "n" + i);
// }
// long end = System.currentTimeMillis();
// System.out.println("Simple@Sharing SET: " + ((end - start)/1000.0) + " seconds");
// sharding.disconnect(); /**************************分布式直连同步调用**************************/
/**
* 分布式直连异步调用
* 线程不安全的,不建议在线程池中使用直连
*/
// List<JedisShardInfo> shards = Arrays.asList(
// new JedisShardInfo("localhost",6379),
// new JedisShardInfo("localhost",6380));
// ShardedJedis sharding = new ShardedJedis(shards);
// ShardedJedisPipeline pipeline = sharding.pipelined();
// long start = System.currentTimeMillis();
// for (int i = 0; i < 100000; i++) {
// pipeline.set("sp" + i, "p" + i);
// }
// List<Object> results = pipeline.syncAndReturnAll();
// long end = System.currentTimeMillis();
// System.out.println("Pipelined@Sharing SET: " + ((end - start)/1000.0) + " seconds");
// sharding.disconnect(); /**************************分布式连接池同步调用**************************/
/**
* 同步方式
*/
// List<JedisShardInfo> shards = Arrays.asList(
// new JedisShardInfo("localhost",6379),
// new JedisShardInfo("localhost",6380));
//
// ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);
//
// ShardedJedis one = pool.getResource();
//
// long start = System.currentTimeMillis();
// for (int i = 0; i < 100000; i++) {
// String result = one.set("spn" + i, "n" + i);
// }
// long end = System.currentTimeMillis();
// pool.returnResource(one);
// System.out.println("Simple@Pool SET: " + ((end - start)/1000.0) + " seconds");
//
// pool.destroy();
// /**************************分布式连接池异步调用**************************/
/**
* 异步方式
*/
// List<JedisShardInfo> shards = Arrays.asList(
// new JedisShardInfo("localhost",6379),
// new JedisShardInfo("localhost",6380));
//
// ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);
//
// ShardedJedis one = pool.getResource();
//
// ShardedJedisPipeline pipeline = one.pipelined();
//
// long start = System.currentTimeMillis();
// for (int i = 0; i < 100000; i++) {
// pipeline.set("sppn" + i, "n" + i);
// }
// List<Object> results = pipeline.syncAndReturnAll();
// long end = System.currentTimeMillis();
// pool.returnResource(one);
// System.out.println("Pipelined@Pool SET: " + ((end - start)/1000.0) + " seconds");
// pool.destroy(); /**************************其他**************************/ /**
* 清空所有
*/
// js.flushAll(); /**
* 销毁链接
*/
// js.disconnect(); }

开始贴代码了,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> <!-- 引入 spring -->
<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> <!-- 引入 springMVC -->
<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> <!-- 编码 UTF-8 -->
<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>

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>

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"> <!-- 使用@Controllers前配置 -->
<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/" /> <!-- 使用jsp作为视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<!-- 目标路径返回到pages下 使用jsp作为视图 -->
<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>

先把这些贴上来是因为这些文件内容都和上篇博文”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" >
<!-- IP:Port -->
<constructor-arg index="0" type="List">
<list>
<value>127.0.0.1:6379</value>
<value>192.168.3.27:6380</value>
</list>
</constructor-arg>
<!-- maxWaitMillis -->
<constructor-arg index="1" type="long">
<value>1000</value>
</constructor-arg>
<!-- MaxIdle -->
<constructor-arg index="2" type="int">
<value>200</value>
</constructor-arg>
<!-- testOnBorrow -->
<constructor-arg index="3" type="Boolean">
<value>true</value>
</constructor-arg>
</bean> </beans>

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();
} }

TestRequest.java

刚才我们写的index.jsp中,提交了表单后浏览器会发起请求,spring拦截请求后会找到注解匹配的类中的方法,TestRequest就是了。

package com.test.web;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView; import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline; import 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; i < 99999; i++) {
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);//睡5秒,然后打印jedis返回的结果
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("返回结果:"+results);
m.addObject("returnMsg","么么哒!");
return m;
} }

存完之后,我们可以取一下试试,看看到底有没有存进去。

看,取到了吧~

使用jedis的时候要注意配合commons-pool2.jar使用,否则会报错的。

原因是 JedisPoolConfig extends GenericObjectPoolConfig,

而GenericObjectPoolConfig则是:

BaseObjectPoolConfig则是:

jar包下载:http://pan.baidu.com/s/1jGBVJds

springMVC整合jedis+redis,以注解形式使用的更多相关文章

  1. springMVC整合jedis+redis

    http://www.cnblogs.com/zhengbn/p/4140549.html 前两天写过 springMVC+memcached 的整合,我从这个基础上改造一下,把redis和sprin ...

  2. springMVC整合memcached,以注解形式使用

    睡不着,深夜写点博客.闲下来有一个月了,心里多少有点…… 在北京找工作一再受阻,这个时间点也不好找 再接再厉 之前没有用过memcached,没有什么实战经验,看了一些关于memcached的博客,写 ...

  3. SpringMVC整合mybatis基于纯注解配置

    Mybatis整合Spring配置 第一部分:配置Spring框架 配置SpringMVC的步骤 配置流程图 导入包(哪些包,基本包5个,1日志依赖包,2webmvc支持包)SpringMVC配置 & ...

  4. springboot整合redis(注解形式)

    springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ...

  5. springmvc整合redis架构搭建实例

    新换环境,又有新东西可以学习了,哈皮! 抽空学习之余看了一下redis,个人对Springmvc的爱是忠贞不渝,所以整理了一下Springmvc整合redis的环境搭建.分享学习. 第一步: 创建ma ...

  6. 安全框架 - Shiro与springMVC整合的注解以及JSP标签

    Shiro想必大家都知道了,之前的文章我也有提过,是目前使用率要比spring security都要多的一个权限框架,本身spring自己都在用shiro,之前的文章有兴趣可以去扒一下 最近正好用到s ...

  7. redis集群配置,spring整合jedis,缓存同步

    前台的商品数据(图片等加载缓慢)查询,先从redis缓存查询数据. redis是一个nosql数据库,内存版数据库,读取速度11w/s.本身具有内存淘汰机制,是单线程服务器(分时操作系统),线程安全. ...

  8. ssm+redis整合(通过aop自定义注解方式)

    此方案借助aop自定义注解来创建redis缓存机制. 1.创建自定义注解类 package com.tp.soft.common.util; import java.lang.annotation.E ...

  9. springmvc注解形式的开发参数接收

    springmvc基于注解的开发 注解第一个例子 1. 创建web项目 springmvc-2 2. 在springmvc的配置文件中指定注解驱动,配置扫描器 <!-- sprimgmvc 注解 ...

随机推荐

  1. HDOJ(HDU) 2520 我是菜鸟,我怕谁(等差数列)

    Problem Description lin2144是一只小菜鸟,都是笨鸟先飞,lin2144想来个菜鸟先飞,他从0点出发 一开始的飞行速度为1m/s,每过一个单位时间lin2144的飞行速度比上一 ...

  2. UVA 11021 Tribles(递推+概率)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33059 [思路] 递推+概率. 设f[i]表示一只Tribble经 ...

  3. 爬虫技术浅析 | z7y Blog

    爬虫技术浅析 | z7y Blog 爬虫技术浅析

  4. linux —— 学习笔记(文件、文件夹操作)

    目录:1.常用的文件文件夹操作 2.文件属性的设置 1.常用的文件文件夹操作 mkdir  创建文件夹 -p 如果指定 a/b/c 时 a .b 不存在,一起创建出来 cp       复制文件或文件 ...

  5. java如何遍历hashMap

    通过Map的entrySet方法.将返回一个set集合.然后遍历这个set集合: package com.howlaa.day04; import java.util.HashMap; import ...

  6. 【Android - 框架】之刷新加载框架Ultra-Pull-To-Refresh的使用

    Ultra-Pull-To-Refresh框架是用来嵌套其他布局,实现下拉刷新和上拉加载的框架.它其中可以嵌套任何控件,ListView.GridView.ScrollView.RecyclerVie ...

  7. IIS7 和IIS8.0 HTTP 错误 500.19 - Internal Server Error 问题的解决方式

    百度了好久,没找到解决这个问题确切的答案,我也知道肯定是权限的问题,当然,经过一番尝试之后,最终攻克了,解决之道例如以下(个人方法,能够一试): 1.找到你的配置文件所在的目录,我的是 E:\源代码\ ...

  8. hive 配置文件以及join中null值的处理

    一.Hive的參数设置 1.  三种设定方式:配置文件 ·   用户自己定义配置文件:$HIVE_CONF_DIR/hive-site.xml ·   默认配置文件:$HIVE_CONF_DIR/hi ...

  9. 转自知乎,亲民好酒推荐 分类: fool_tree的笔记本 2014-11-08 17:37 652人阅读 评论(0) 收藏

    这里尽量为大家推荐一些符合大众喜好.业内公认好评."即使你不喜欢,你也会承认它不错"的酒款.而且介绍到的酒款还会有一个共同的特征,就是能让你方便的在网上买到. 大概会分为烈酒,利口 ...

  10. c++ 字符串流 sstream(常用于格式转换) 分类: C/C++ 2014-11-08 17:20 150人阅读 评论(0) 收藏

    使用stringstream对象简化类型转换 C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能,即单纯性.类型安全和可扩展性.在本文中 ...