• 架构之路之spring+redis的集成


    1.前言

           Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。我们都知道,在日常的应用中,数据库瓶颈是最容易出现的。数据量太大和频繁的查询,由于磁盘IO性能的局限性,导致项目的性能越来越低。这时候,基于内存的缓存框架,就能解决我们很多问题。例如Memcache,Redis等。将一些频繁使用的数据放入缓存读取,大大降低了数据库的负担。提升了系统的性能。

          有于Memcached,对于缓存对象大小有要求,单个对象不得大于1MB,且不支持复杂的数据类型,譬如SET等。因此现在Redis用的越来越多。

    2.引入依赖

    [java] view plain copy
     
    1. <dependency>  
    2.             <groupId>org.springframework.data</groupId>  
    3.             <artifactId>spring-data-redis</artifactId>  
    4.             <version>1.7.2.RELEASE</version>  
    5.         </dependency>  
    6.         <dependency>  
    7.             <groupId>redis.clients</groupId>  
    8.             <artifactId>jedis</artifactId>  
    9.             <version>2.8.1</version>  
    10.         </dependency>  

    3.配置文件

    3.1 redis.properties

    [java] view plain copy
     
    1. #访问地址  
    2. redis.host=127.0.0.1  
    3. #访问端口  
    4. redis.port=6379  
    5. #注意,如果没有password,此处不设置值,但这一项要保留  
    6. redis.password=  
    7.   
    8. #最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。  
    9. redis.maxIdle=300  
    10. #连接池的最大数据库连接数。设为0表示无限制  
    11. redis.maxActive=600  
    12. #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。  
    13. redis.maxWait=1000  
    14. #在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;  
    15. redis.testOnBorrow=true  

    3.2 redis-context.xml

    [java] view plain copy
     
    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:tx="http://www.springframework.org/schema/tx"  
    6.        xmlns:context="http://www.springframework.org/schema/context"  
    7.        xsi:schemaLocation="  
    8.       http://www.springframework.org/schema/beans  
    9.       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    10.       http://www.springframework.org/schema/tx  
    11.       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    12.       http://www.springframework.org/schema/context  
    13.       http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    14.   
    15.     <!-- scanner redis properties  -->  
    16.     <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>  
    17.   
    18.     <!--(1)如果你有多个数据源需要通过<context:property-placeholder管理,且不愿意放在一个配置文件里,那么一定要加上ignore-unresolvable=“true"-->  
    19.     <!--(2)注意新版的(具体从哪个版本开始不清楚,有兴趣可以查一下)JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码。-->  
    20.     <!-- redis连接池 -->  
    21.     <bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig">  
    22.         <property name="maxTotal" value="${redis.maxActive}"></property>  
    23.         <property name="maxIdle" value="${redis.maxIdle}"></property>  
    24.         <property name="maxWaitMillis" value="${redis.maxWait}"></property>  
    25.         <property name="testOnBorrow" value="${redis.testOnBorrow}"></property>  
    26.     </bean>  
    27.     <!-- redis连接工厂 -->  
    28.     <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
    29.         <property name="hostName" value="${redis.host}"></property>  
    30.         <property name="port" value="${redis.port}"></property>  
    31.         <property name="password" value="${redis.password}"></property>  
    32.         <property name="poolConfig" ref="jedisConfig"></property>  
    33.     </bean>  
    34.     <!-- redis操作模板,这里采用尽量面向对象的模板 -->  
    35.     <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
    36.         <property name="connectionFactory" ref="connectionFactory"/>  
    37.         <!--     如果不配置Serializer,那么存储的时候只能使用String,如果用对象类型存储,那么会提示错误 can't cast to String!!!-->  
    38.         <property name="keySerializer">  
    39.             <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>  
    40.         </property>  
    41.         <property name="valueSerializer">  
    42.             <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
    43.         </property>  
    44.         <!--开启事务-->  
    45.         <property name="enableTransactionSupport" value="true"/>  
    46.     </bean>  
    47. </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"/>即可!

    4.测试

    [java] view plain copy
     
    1. @Test  
    2.     public void testSpringRedis() {  
    3.         //stringRedisTemplate的操作  
    4.         // String读写  
    5.         redisTemplate.delete("myStr");  
    6.         redisTemplate.opsForValue().set("myStr", "skyLine");  
    7.         System.out.println(redisTemplate.opsForValue().get("myStr"));  
    8.         System.out.println("---------------");  
    9.   
    10.         // List读写  
    11.         redisTemplate.delete("myList");  
    12.         redisTemplate.opsForList().rightPush("myList", "T");  
    13.         redisTemplate.opsForList().rightPush("myList", "L");  
    14.         redisTemplate.opsForList().leftPush("myList", "A");  
    15.         List<String> listCache = redisTemplate.opsForList().range(  
    16.                 "myList", 0, -1);  
    17.         for (String s : listCache) {  
    18.             System.out.println(s);  
    19.         }  
    20.         System.out.println("---------------");  
    21.   
    22.         // Set读写  
    23.         redisTemplate.delete("mySet");  
    24.         redisTemplate.opsForSet().add("mySet", "A");  
    25.         redisTemplate.opsForSet().add("mySet", "B");  
    26.         redisTemplate.opsForSet().add("mySet", "C");  
    27.         Set<String> setCache = redisTemplate.opsForSet().members(  
    28.                 "mySet");  
    29.         for (String s : setCache) {  
    30.             System.out.println(s);  
    31.         }  
    32.         System.out.println("---------------");  
    33.   
    34.         // Hash读写  
    35.         redisTemplate.delete("myHash");  
    36.         redisTemplate.opsForHash().put("myHash", "BJ", "北京");  
    37.         redisTemplate.opsForHash().put("myHash", "SH", "上海");  
    38.         redisTemplate.opsForHash().put("myHash", "HN", "河南");  
    39.         Map<String, String> hashCache = redisTemplate.opsForHash()  
    40.                 .entries("myHash");  
    41.         for (Map.Entry entry : hashCache.entrySet()) {  
    42.             System.out.println(entry.getKey() + " - " + entry.getValue());  
    43.         }  
    44.         System.out.println("---------------");  
    45.     }  
    结果:
    [java] view plain copy
     
    1. skyLine  
    2. ---------------  
    3. A  
    4. T  
    5. L  
    6. ---------------  
    7. C  
    8. B  
    9. A  
    10. ---------------  
    11. HN - 河南  
    12. BJ - 北京  
    13. SH - 上海  
    14. ---------------  

    上面的代码基本使用的是StringRedisTemplate接口,redisTemplate还提供了list,set,hash类型,同时也可以保存javaBean对象,前提是改对象实现Serializable接口,下面是提出的公共方法:

    [java] view plain copy
     
    1. package com.tl.skyLine.helper;  
    2.   
    3. import org.springframework.data.redis.core.*;  
    4.   
    5. import java.util.List;  
    6. import java.util.Map;  
    7. import java.util.Set;  
    8.   
    9. /** 
    10.  * Created by tl on 17/2/16. 
    11.  */  
    12. public class RedisTemplateUtil {  
    13.   
    14.     private RedisTemplate redisTemplate;  
    15.   
    16.     public RedisTemplateUtil(RedisTemplate redisTemplate) {  
    17.         this.redisTemplate = redisTemplate;  
    18.     }  
    19.   
    20.   
    21.     public void set(String key, Object value) {  
    22.         ValueOperations valueOperations = redisTemplate.opsForValue();  
    23.         valueOperations.set(key, value);  
    24.   
    25.         //BoundValueOperations的理解对保存的值做一些细微的操作  
    26. //        BoundValueOperations boundValueOperations = redisTemplate.boundValueOps(key);  
    27.     }  
    28.   
    29.     public Object get(String key) {  
    30.         return redisTemplate.opsForValue().get(key);  
    31.     }  
    32.   
    33.     public void setList(String key, List<?> value) {  
    34.         ListOperations listOperations = redisTemplate.opsForList();  
    35.         listOperations.leftPush(key, value);  
    36.     }  
    37.   
    38.     public Object getList(String key) {  
    39.         return redisTemplate.opsForList().leftPop(key);  
    40.     }  
    41.   
    42.     public void setSet(String key, Set<?> value) {  
    43.         SetOperations setOperations = redisTemplate.opsForSet();  
    44.         setOperations.add(key, value);  
    45.     }  
    46.   
    47.     public Object getSet(String key) {  
    48.         return redisTemplate.opsForSet().members(key);  
    49.     }  
    50.   
    51.   
    52.     public void setHash(String key, Map<String, ?> value) {  
    53.         HashOperations hashOperations = redisTemplate.opsForHash();  
    54.         hashOperations.putAll(key, value);  
    55.     }  
    56.   
    57.     public Object getHash(String key) {  
    58.         return redisTemplate.opsForHash().entries(key);  
    59.     }  
    60.   
    61.   
    62.     public void delete(String key) {  
    63.         redisTemplate.delete(key);  
    64.     }  
    65.   
    66. //    public void clearAll(){  
    67. //        redisTemplate.multi();  
    68. //    }  
  • 相关阅读:
    nginx 配置优化(简单)
    Nginx 安装
    Smokeping安装教程
    test [ ] 四类
    if语句中的判断条件(nginx)
    力扣 1431. 拥有最多糖果的孩子 python
    力扣 1672. 最富有客户的资产总量+1512. 好数对的数目 python
    力扣 剑指 Offer 58
    力扣 8. 字符串转换整数 (atoi)python--每日一题
    力扣 7. 整数反转python 每日一题
  • 原文地址:https://www.cnblogs.com/wojiaochuichui/p/8662151.html
Copyright © 2020-2023  润新知