1.前言
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。我们都知道,在日常的应用中,数据库瓶颈是最容易出现的。数据量太大和频繁的查询,由于磁盘IO性能的局限性,导致项目的性能越来越低。这时候,基于内存的缓存框架,就能解决我们很多问题。例如Memcache,Redis等。将一些频繁使用的数据放入缓存读取,大大降低了数据库的负担。提升了系统的性能。
有于Memcached,对于缓存对象大小有要求,单个对象不得大于1MB,且不支持复杂的数据类型,譬如SET等。因此现在Redis用的越来越多。
2.引入依赖
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-redis</artifactId>
- <version>1.7.2.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.8.1</version>
- </dependency>
3.配置文件
3.1 redis.properties
- #访问地址
- redis.host=127.0.0.1
- #访问端口
- redis.port=6379
- #注意,如果没有password,此处不设置值,但这一项要保留
- redis.password=
- #最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
- redis.maxIdle=300
- #连接池的最大数据库连接数。设为0表示无限制
- redis.maxActive=600
- #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
- redis.maxWait=1000
- #在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
- redis.testOnBorrow=true
3.2 redis-context.xml
- <?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:p="http://www.springframework.org/schema/p"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd">
- <!-- scanner redis properties -->
- <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>
- <!--(1)如果你有多个数据源需要通过<context:property-placeholder管理,且不愿意放在一个配置文件里,那么一定要加上ignore-unresolvable=“true"-->
- <!--(2)注意新版的(具体从哪个版本开始不清楚,有兴趣可以查一下)JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码。-->
- <!-- redis连接池 -->
- <bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig">
- <property name="maxTotal" value="${redis.maxActive}"></property>
- <property name="maxIdle" value="${redis.maxIdle}"></property>
- <property name="maxWaitMillis" value="${redis.maxWait}"></property>
- <property name="testOnBorrow" value="${redis.testOnBorrow}"></property>
- </bean>
- <!-- redis连接工厂 -->
- <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
- <property name="hostName" value="${redis.host}"></property>
- <property name="port" value="${redis.port}"></property>
- <property name="password" value="${redis.password}"></property>
- <property name="poolConfig" ref="jedisConfig"></property>
- </bean>
- <!-- redis操作模板,这里采用尽量面向对象的模板 -->
- <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
- <property name="connectionFactory" ref="connectionFactory"/>
- <!-- 如果不配置Serializer,那么存储的时候只能使用String,如果用对象类型存储,那么会提示错误 can't cast to String!!!-->
- <property name="keySerializer">
- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
- </property>
- <property name="valueSerializer">
- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
- </property>
- <!--开启事务-->
- <property name="enableTransactionSupport" value="true"/>
- </bean>
- </beans>
注意事项:
由于我们之前引用了mongo配置文件的properties读取,所以这里的<context:property-placeholder location="classpath:redis.properties"/>在项目加载的时候无法识别里面的占位符错误"Could not resolve placeholder",主要原因是:
Spring容器采用反射扫描的发现机制,在探测到Spring容器中有一个org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描(Spring 3.1已经使用PropertySourcesPlaceholderConfigurer替代PropertyPlaceholderConfigurer了)。
而<context:property-placeholder/>这个基于命名空间的配置,其实内部就是创建一个PropertyPlaceholderConfigurer Bean而已。换句话说,即Spring容器仅允许最多定义一个PropertyPlaceholderConfigurer(或<context:property-placeholder/>),其余的会被Spring忽略掉。
解决方法就是改成<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>即可!
结果:
上面的代码基本使用的是StringRedisTemplate接口,redisTemplate还提供了list,set,hash类型,同时也可以保存javaBean对象,前提是改对象实现Serializable接口,下面是提出的公共方法:
解决方法就是改成<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>即可!
4.测试
- @Test
- public void testSpringRedis() {
- //stringRedisTemplate的操作
- // String读写
- redisTemplate.delete("myStr");
- redisTemplate.opsForValue().set("myStr", "skyLine");
- System.out.println(redisTemplate.opsForValue().get("myStr"));
- System.out.println("---------------");
- // List读写
- redisTemplate.delete("myList");
- redisTemplate.opsForList().rightPush("myList", "T");
- redisTemplate.opsForList().rightPush("myList", "L");
- redisTemplate.opsForList().leftPush("myList", "A");
- List<String> listCache = redisTemplate.opsForList().range(
- "myList", 0, -1);
- for (String s : listCache) {
- System.out.println(s);
- }
- System.out.println("---------------");
- // Set读写
- redisTemplate.delete("mySet");
- redisTemplate.opsForSet().add("mySet", "A");
- redisTemplate.opsForSet().add("mySet", "B");
- redisTemplate.opsForSet().add("mySet", "C");
- Set<String> setCache = redisTemplate.opsForSet().members(
- "mySet");
- for (String s : setCache) {
- System.out.println(s);
- }
- System.out.println("---------------");
- // Hash读写
- redisTemplate.delete("myHash");
- redisTemplate.opsForHash().put("myHash", "BJ", "北京");
- redisTemplate.opsForHash().put("myHash", "SH", "上海");
- redisTemplate.opsForHash().put("myHash", "HN", "河南");
- Map<String, String> hashCache = redisTemplate.opsForHash()
- .entries("myHash");
- for (Map.Entry entry : hashCache.entrySet()) {
- System.out.println(entry.getKey() + " - " + entry.getValue());
- }
- System.out.println("---------------");
- }
- skyLine
- ---------------
- A
- T
- L
- ---------------
- C
- B
- A
- ---------------
- HN - 河南
- BJ - 北京
- SH - 上海
- ---------------
上面的代码基本使用的是StringRedisTemplate接口,redisTemplate还提供了list,set,hash类型,同时也可以保存javaBean对象,前提是改对象实现Serializable接口,下面是提出的公共方法:
- package com.tl.skyLine.helper;
- import org.springframework.data.redis.core.*;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- /**
- * Created by tl on 17/2/16.
- */
- public class RedisTemplateUtil {
- private RedisTemplate redisTemplate;
- public RedisTemplateUtil(RedisTemplate redisTemplate) {
- this.redisTemplate = redisTemplate;
- }
- public void set(String key, Object value) {
- ValueOperations valueOperations = redisTemplate.opsForValue();
- valueOperations.set(key, value);
- //BoundValueOperations的理解对保存的值做一些细微的操作
- // BoundValueOperations boundValueOperations = redisTemplate.boundValueOps(key);
- }
- public Object get(String key) {
- return redisTemplate.opsForValue().get(key);
- }
- public void setList(String key, List<?> value) {
- ListOperations listOperations = redisTemplate.opsForList();
- listOperations.leftPush(key, value);
- }
- public Object getList(String key) {
- return redisTemplate.opsForList().leftPop(key);
- }
- public void setSet(String key, Set<?> value) {
- SetOperations setOperations = redisTemplate.opsForSet();
- setOperations.add(key, value);
- }
- public Object getSet(String key) {
- return redisTemplate.opsForSet().members(key);
- }
- public void setHash(String key, Map<String, ?> value) {
- HashOperations hashOperations = redisTemplate.opsForHash();
- hashOperations.putAll(key, value);
- }
- public Object getHash(String key) {
- return redisTemplate.opsForHash().entries(key);
- }
- public void delete(String key) {
- redisTemplate.delete(key);
- }
- // public void clearAll(){
- // redisTemplate.multi();
- // }