JavaSpringmvc操作Redis和Redis集群

前端之家收集整理的这篇文章主要介绍了JavaSpringmvc操作Redis和Redis集群前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

《JavaSpringmvc操作Redis和Redis集群》要点:
本文介绍了JavaSpringmvc操作Redis和Redis集群,希望对您有用。如果有疑问,可以联系我们。

关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用

Redis 是什么,能做什么

Redis 是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型.内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel 提供高可用,通过 Redis Cluster 提供自动分区.(摘自 Redis 官网)

作为内存数据库,在现代互联网 web 系统中,还是主要将 Redis 作为缓存使用.大型互联网 Web 系统对性能要求很高,而在前端和数据层之间增加数据缓存已成为必不可少的手段之一,当前比较流行的两个技术就是 Redis 和 Memcached,至于两者有什么区别,不是本文要说的内容.本文主要讲 Java web 如何操作 Redis 及 Redis 集群.

一般 Java 程序操作Redis

Redis 提供了多种语言的客户端,在 Java 中最流行的是 Jedis .访问可查看源码及使用方式.目前 Jedis 最新版本是2.9.0.无论是单机还是集群,Jedis 都有很详细的说明和实例代码,这里只做简单说明.如果用 Maven 做包管理,需要引用 jedis 包,本例使用最新的2.9.0版本,如下:

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.9.0</version>

</dependency>

操作 Redis 单机

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

/**

* Created by fengdezitai on 2016/10/9.

*/

public class JedisClient {

private static final String host= "192.168.31.121";

private static final JedisClient jedisClient = new JedisClient();

private Jedis jedis = null;

/**

* 私有构造函数

*/

private JedisClient(){}

public static JedisClient getInstance(){

return jedisClient;

}

private JedisPoolConfig getPoolConfig(){

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

jedisPoolConfig.setMaxIdle(10);

jedisPoolConfig.setMaxTotal(100);

jedisPoolConfig.setMaxWaitMillis(3000);

return jedisPoolConfig;

}

/**

* 添加

* @param key

* @param value

* @return

* @throws Exception

*/

public Boolean add(String key,String value) throws Exception{

JedisPool pool = new JedisPool(getPoolConfig(),host);

Jedis jedis = null;

try {

jedis = pool.getResource();

if(jedis.exists(key)){

throw new Exception(String.format("key (%s) 已存在 ",key));

}

jedis.set(key,value);

}catch (Exception e){

throw e;

}

finally {

if(jedis!=null){

jedis.close();

}

}

pool.destroy();

return true;

}

/**

* 获取

* @param key

* @return

* @throws Exception

*/

public String get(String key) throws Exception{

JedisPool pool = new JedisPool(getPoolConfig(),host);

Jedis jedis = null;

String result = "";

try {

jedis = pool.getResource();

result = jedis.get(key);

}catch (Exception e){

throw e;

}

finally {

if(jedis!=null){

jedis.close();

}

}

pool.destroy();

return result;

}

public static void main(String[] args) {

JedisClient jedisClient = JedisClient.getInstance();

try {

/*Boolean result = jedisClient.add("hello","redis1");

if(result){

System.out.println("success");

}*/

System.out.println(jedisClient.get("hello"));

}catch (Exception e){

e.printStackTrace();

}

}

}

操作 redis 集群

import redis.clients.jedis.*;

import java.util.HashSet;

import java.util.Set;

/**

* Created by fengdezitai on 2016/10/13.

*/

public class JedisClusterClient {

private static int count = 0;

private static final JedisClusterClient redisClusterClient = new JedisClusterClient();

/**

* 私有构造函数

*/

private JedisClusterClient() {}

public static JedisClusterClient getInstance() {

return redisClusterClient;

}

private JedisPoolConfig getPoolConfig(){

JedisPoolConfig config = new JedisPoolConfig();

config.setMaxTotal(1000);

config.setMaxIdle(100);

config.setTestOnBorrow(true);

return config;

}

public void SaveRedisCluster() {

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();

jedisClusterNodes.add(new HostAndPort("192.168.31.245",7000));

jedisClusterNodes.add(new HostAndPort("192.168.31.245",7001));

jedisClusterNodes.add(new HostAndPort("192.168.31.245",7002));

jedisClusterNodes.add(new HostAndPort("192.168.31.210",7003));

jedisClusterNodes.add(new HostAndPort("192.168.31.210",7004));

jedisClusterNodes.add(new HostAndPort("192.168.31.210",7005));

JedisCluster jc = new JedisCluster(jedisClusterNodes,getPoolConfig());

jc.set("cluster","this is a redis cluster");

String result = jc.get("cluster");

System.out.println(result);

}

public static void main(String[] args) {

JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();

jedisClusterClient.SaveRedisCluster();

}

}

Spring mvc 操作 Redis

在 Spring mvc 中操作 Redis,首先当然要搭好 Spring mvc 框架了.以下是在假设 Spring mvc 环境已经架好的情况下.本例中 Spring 版本为 4.3.2 RELEASE.关于 Spring 的 maven 引用如下:

<!-- spring版本号 -->

<spring.version>4.3.2.RELEASE</spring.version>

<!-- spring核心包 -->

<!-- springframe start -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<version>${spring.version}</version>

<exclusions>

<exclusion>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-oxm</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-tx</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${spring.version}</version>

<exclusions>

<exclusion>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aop</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-test</artifactId>

<version>${spring.version}</version>

</dependency>

<!-- springframe end -->

操作 Redis 单机

只用 Jedis 自己实现注入(区别于下面的引用spring-data-redis)

把前面的 JedisClient 代码拿过来引用即可,只需实现一���访问 Redis 的 Service,就可以集成到 Spring mvc .Service 代码如下:

import org.springframework.stereotype.Service;

import util.JedisClient;

/**

* Created by fengdezitai on 2016/10/9.

*/

@Service

public class RedisService {

public String get(String key) throws Exception{

JedisClient jedisClient = JedisClient.getInstance(); //上面实现的JedisClient

String result = "";

try {

result = jedisClient.get("hello");

}catch (Exception e){

throw e;

}

return result;

}

}

Controller 实现如下:

@Controller

@RequestMapping(value = "redisAllInOne")

public class RedisAllInOneController {

@Autowired

private RedisService redisService;

@RequestMapping(value = "get",method = RequestMethod.GET)

@ResponseBody

public Object getByMyService(String key){

try {

String result = redisService.get(key);

return result;

}catch (Exception e){

e.printStackTrace();

}

return null;

}

}

用 spring-data-redis 包做集成

上面是自己实现的注入,这里用 spring-data-redis 进行集成,只需简单配置即可,需要引用 maven 包如下,版本为目前最新版 1.7.2.RELEASE:

<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-redis</artifactId>

<version>1.7.2.RELEASE</version>

</dependency>

使用 spring-data-redis,即省去了自己实现注入的过程,通过它提供的一些配置,即可实现连接池配置、RedisTemplate 配置、JedisConnectionFactory 配置;通过 JedisConnectionFactory 可配置连接池参数、redis 服务器、端口、密码、超时时间、database索引等;RedisTemplate 即注入的bean,可以使用 RedisTemplate 自动注入的实体进行 redis 的一系列操作,具体看配置;

redis 服务属性配置文件

redis.maxIdle=300

redis.maxWait=3000

redis.testOnBorrow=true

redis.host=192.168.31.121

redis.port=6379

redis.password=password

redis.timeout=3000

spring-data-redis xml 配置文件 redis-context.xml:

<!-- jedis 连接池 配置 -->

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >

<property name="maxIdle" value="${redis.maxIdle}" />

<property name="maxWaitMillis" value="${redis.maxWait}" />

<property name="testOnBorrow" value="${redis.testOnBorrow}" />

</bean>

<!-- redis服务器中心 -->

<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >

<property name="poolConfig" ref="poolConfig" />

<property name="port" value="${redis.port}" />

<property name="hostName" value="${redis.host}" />

<!--<property name="password" value="${redis.password}" />-->

<property name="timeout" value="${redis.timeout}" ></property>

<property name="database" value="1"></property>

</bean>

<bean id="commonRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >

<property name="connectionFactory" ref="connectionFactory" />

<property name="keySerializer" ref="stringRedisSerializer" />

<property name="hashKeySerializer" ref="stringRedisSerializer" />

<property name="valueSerializer" ref="stringRedisSerializer" />

<property name="hashValueSerializer" ref="stringRedisSerializer" />

</bean>

<bean id="connectionFactory1" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >

<property name="poolConfig" ref="poolConfig" />

<property name="port" value="${redis.port}" />

<property name="hostName" value="${redis.host}" />

<!--<property name="password" value="${redis.password}" />-->

<property name="timeout" value="${redis.timeout}" ></property>

<property name="database" value="2"></property>

</bean>

<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />

<bean id="cacheRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >

<property name="connectionFactory" ref="connectionFactory1" />

<property name="keySerializer" ref="stringRedisSerializer" />

<property name="hashKeySerializer" ref="stringRedisSerializer" />

<property name="valueSerializer" ref="stringRedisSerializer" />

<property name="hashValueSerializer" ref="stringRedisSerializer" />

</bean>

之后在 spring 配置文件中引用以上文件

<import resource="redis-context.xml" />

解释一下上面的配置:

poolConfig 即配置 redis 连接池,之后配置了两个 JedisConnectionFactory 和 RedisTemplate,一个 RedisTemplate 对应一个 JedisConnectionFactory,这样可以配置根据场景配置不同的 Redis 连接,比如超时时间要求不一致、database 0-15 可以存储不同的数据等.这里就配置了database 1 和 2,调用 commonRedisTemplate 会存到 database1,调用 cacheRedisTemplate 会存到 database2.

之后在 Service 层即可注入并引用这两个 RedisTemplate,如下代码

import org.apache.commons.lang3.StringUtils;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Repository;import javax.annotation.Resource;import java.io.*;@Repositorypublic class RedisCache {

@Resource(name = "cacheRedisTemplate") private RedisTemplate<String,String> cacheRedisTemplate; public void put(Object key,Object value) { if(null == value) { return; } if(value instanceof String) { if(StringUtils.isEmpty(value.toString())) { return; } } // TODO Auto-generated method stub final String keyf = key + ""; final Object valuef = value; final long liveTime = 86400; cacheRedisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { byte[] keyb = keyf.getBytes(); byte[] valueb = toByteArray(valuef); connection.set(keyb,valueb); if (liveTime > 0) { connection.expire(keyb,liveTime); } return 1L; } }); } public Object get(Object key) { final String keyf = (String) key; Object object; object = cacheRedisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = keyf.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } return toObject(value); } }); return object; } /** * 描述 : <byte[]转Object>. <br> * <p> * <使用方法说明> * </p> * * @param bytes * @return */ private Object toObject(byte[] bytes) { Object obj = null; try { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); obj = ois.readObject(); ois.close(); bis.close(); } catch (IOException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } return obj; } private byte[] toByteArray(Object obj) { byte[] bytes = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.flush(); bytes = bos.toByteArray(); oos.close(); bos.close(); } catch (IOException ex) { ex.printStackTrace(); } return bytes; }}

最后在 Controller 中调用即可

@Autowired

private RedisCache redisCache;

@RequestMapping(value = "get",method = RequestMethod.GET)

@ResponseBody

public Object getByMyService(String key) {

try {

String result = redisService.get(key);

return result;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

@RequestMapping(value = "save",method = RequestMethod.GET)

@ResponseBody

public Object save() {

Token token = new Token();

token.setAccess_token("token");

token.setExpires_in(1000);

try {

redisCache.put("token",token);

} catch (Exception e) {

e.printStackTrace();

}

return "ok";

}

操作 Redis 集群

只用 Jedis 自己实现注入(区别于下面的引用spring-data-redis)

把前面的 JedisClusterClient 代码拿过来引用即可,只需实现一个访问 Redis 的 Service,就可以集成到 Spring mvc .Service 代码如下:

import org.springframework.stereotype.Service;

import util.JedisClusterClient;

/**

* Created by fengdezitai on 2016/10/13.

*/

@Service

public class RedisClusterService {

public void save() throws Exception{

//调用 JedisClusterClient 中的方法

JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();

try {

jedisClusterClient.SaveRedisCluster();

}catch (Exception e){

throw e;

}

}

}

最后在 Controller 中调用实现的 Service 即可

@Controller

@RequestMapping(value = "redisCluster")

public class RedisClusterController {

@Autowired

private RedisClusterService redisClusterService;

@RequestMapping(value = "save",method = RequestMethod.GET)

@ResponseBody

public Object save(){

try{

redisClusterService.save();

}catch (Exception e){

e.printStackTrace();

return String.format("error: %s",e.getMessage());

}

return "ok";

}

}

用 spring-data-redis 包做集成

Spring 和 spring-data-redis maven 包引用和前面一致,之所以引用 spring-data-redis 1.7.2.RELEASE,是因为目前只有这个最新版本才支持集群操作.

redis 集群服务属性配置

redis.maxIdle=300

redis.maxWait=3000

redis.testOnBorrow=false

redis.timeout=3000

spring-data-redis xml 集群配置文件 redis-cluster-context.xml

<!-- 连接池 配置 -->

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >

<property name="maxIdle" value="${redis.maxIdle}" />

<property name="maxWaitMillis" value="${redis.maxWait}" />

<property name="testOnBorrow" value="${redis.testOnBorrow}" />

</bean>

<bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">

<property name="maxRedirects" value="3"></property>

<property name="clusterNodes">

<set>

<bean class="org.springframework.data.redis.connection.RedisNode">

<constructor-arg name="host" value="192.168.31.245"></constructor-arg>

<constructor-arg name="port" value="7000"></constructor-arg>

</bean>

<bean class="org.springframework.data.redis.connection.RedisNode">

<constructor-arg name="host" value="192.168.31.245"></constructor-arg>

<constructor-arg name="port" value="7001"></constructor-arg>

</bean>

<bean class="org.springframework.data.redis.connection.RedisNode">

<constructor-arg name="host" value="192.168.31.245"></constructor-arg>

<constructor-arg name="port" value="7002"></constructor-arg>

</bean>

<bean class="org.springframework.data.redis.connection.RedisNode">

<constructor-arg name="host" value="192.168.31.210"></constructor-arg>

<constructor-arg name="port" value="7003"></constructor-arg>

</bean>

<bean class="org.springframework.data.redis.connection.RedisNode">

<constructor-arg name="host" value="192.168.31.210"></constructor-arg>

<constructor-arg name="port" value="7004"></constructor-arg>

</bean>

<bean class="org.springframework.data.redis.connection.RedisNode">

<constructor-arg name="host" value="192.168.31.210"></constructor-arg>

<constructor-arg name="port" value="7005"></constructor-arg>

</bean>

</set>

</property>

</bean>

<bean id="redis4CacheConnectionFactory"

class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

<constructor-arg name="clusterConfig" ref="redisClusterConfig" />

<property name="timeout" value="${redis.timeout}" />

<property name="poolConfig" ref="poolConfig"/>

</bean>

<bean name="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />

<bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

<property name="connectionFactory" ref="redis4CacheConnectionFactory" />

<property name="keySerializer" ref="stringRedisSerializer" />

<property name="hashKeySerializer" ref="stringRedisSerializer" />

<property name="valueSerializer" ref="stringRedisSerializer" />

<property name="hashValueSerializer" ref="stringRedisSerializer" />

</bean>

之后在 Spring 配置文件中引用

<import resource="redis-cluster-context.xml" />

解释以上配置

poolConfig是连接池配置,redisClusterConfig 配置了 Redis 集群的各个节点(节点 host 和 port 最好写在属性配置文件中),集群搭建可见 我的 另一篇博客 .然后下面和单机配置一样了,一对 JedisConnectionFactory 和 RedisTemplate .

之后在 Service 层即可注入并引用这个 RedisTemplate,代码如下:

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.dao.DataAccessException;

import org.springframework.data.redis.connection.RedisConnection;

import org.springframework.data.redis.core.RedisCallback;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Repository;

import java.io.*;

/**

* Created by fengdezitai on 2016/9/29.

*/

@Repository

public class RedisClusterCache {

@Autowired

private RedisTemplate clusterRedisTemplate;

public void put(Object key,Object value) {

if(null == value) {

return;

}

if(value instanceof String) {

if(StringUtils.isEmpty(value.toString())) {

return;

}

}

// TODO Auto-generated method stub

final String keyf = key + "";

final Object valuef = value;

final long liveTime = 86400;

clusterRedisTemplate.execute(new RedisCallback<Long>() {

public Long doInRedis(RedisConnection connection)

throws DataAccessException {

byte[] keyb = keyf.getBytes();

byte[] valueb = toByteArray(valuef);

connection.set(keyb,valueb);

if (liveTime > 0) {

connection.expire(keyb,liveTime);

}

return 1L;

}

});

}

public Object get(Object key) {

final String keyf = (String) key;

Object object;

object = clusterRedisTemplate.execute(new RedisCallback<Object>() {

public Object doInRedis(RedisConnection connection)

throws DataAccessException {

byte[] key = keyf.getBytes();

byte[] value = connection.get(key);

if (value == null) {

return null;

}

return toObject(value);

}

});

return object;

}

/**

* 描述 : <byte[]转Object>. <br>

* <p>

* <使用方法说明>

* </p>

*

* @param bytes

* @return

*/

private Object toObject(byte[] bytes) {

Object obj = null;

try {

ByteArrayInputStream bis = new ByteArrayInputStream(bytes);

ObjectInputStream ois = new ObjectInputStream(bis);

obj = ois.readObject();

ois.close();

bis.close();

} catch (IOException ex) {

ex.printStackTrace();

} catch (ClassNotFoundException ex) {

ex.printStackTrace();

}

return obj;

}

private byte[] toByteArray(Object obj) {

byte[] bytes = null;

ByteArrayOutputStream bos = new ByteArrayOutputStream();

try {

ObjectOutputStream oos = new ObjectOutputStream(bos);

oos.writeObject(obj);

oos.flush();

bytes = bos.toByteArray();

oos.close();

bos.close();

} catch (IOException ex) {

ex.printStackTrace();

}

return bytes;

}

}

最后在 Controller 中调用即可

@Controller

@RequestMapping(value = "redisCluster")

public class RedisClusterController {

@Autowired

private RedisClusterCache redisClusterCache;

@RequestMapping(value = "clusterSave",method = {RequestMethod.GET,RequestMethod.POST})

@ResponseBody

public Object clusterSave(){

//redisClusterCache.put("cluster","save cluster");

Token token = new Token();

token.setExpires_in(1000);

token.setAccess_token("hello world");

redisClusterCache.put("token",token);

return "ok";

}

@RequestMapping(value = "getKey",method = RequestMethod.GET)

@ResponseBody

public Object getCluster(String key){

Object val = redisClusterCache.get(key);

return val;

}

}

注意事项:

  • 版本问题,如果用 spring-data-redis 做集成操作 Reids 集群,只有 spring-data-redis 目前最新版本1.7才包含对集群的操作,而最新的 spring-data-redis 中的某些功能对 Spring mvc 的版本也有些限制,所以尽量选择高版本的 Spring mvc 对应.

  • 如果存储的value值是一个实体对象,那么一定要实现 Serializable 接口

  • 转载自:http://www.cnblogs.com/fengzheng/p/5941953.html

JavaSpringmvc操作Redis和Redis集群

《JavaSpringmvc操作Redis和Redis集群》是否对您有启发,欢迎查看更多与《JavaSpringmvc操作Redis和Redis集群》相关教程,学精学透。编程之家PHP学院为您提供精彩教程。

猜你在找的SpringMVC相关文章