spring + redis 实现数据的缓存

摘要:
因为commons pooljar的目录结构根据版本而改变。以前的版本是org.apache。池,而较新版本是org.apache.pool2…style=“background-color:#0098dd;color:white;font-size:17px;font-weight:bold;”3.关于Redis Redis是一个关键值存储系统。与Memcached类似,它支持更多的存储值类型,包括string、list、set、zset和hash。在此基础上,Redis支持不同方式的排序。与memcached一样,数据被缓存在内存中以确保效率。

1、实现目标

  通过redis缓存数据。(目的不是加快查询的速度,而是减少数据库的负担)  

2、所需jar包

  spring + redis 实现数据的缓存第1张

  注意:jdies和commons-pool两个jar的版本是有对应关系的,注意引入jar包是要配对使用,否则将会报错。因为commons-pooljar的目录根据版本的变化,目录结构会变。前面的版本是org.apache.pool,而后面的版本是org.apache.pool2...

style="background-color: #0098dd; color: white; font-size: 17px; font-weight: bold;"3、redis简介

  redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)

4、编码实现

1)、配置的文件(properties)

  将那些经常要变化的参数配置成独立的propertis,方便以后的修改

  redis.properties

redis.hostName=127.0.0.1
redis.port=6379
redis.timeout=15000
redis.usePool=true

redis.maxIdle=6
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=3
redis.timeBetweenEvictionRunsMillis=60000

2)、spring-redis.xml

  redis的相关参数配置设置。参数的值来自上面的properties文件

<beans xmlns="http://www.springframework.org/schema/beans"   
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.xsd" default-autowire="byName">  
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
        <!-- <property name="maxIdle" value="6"></property>  
        <property name="minEvictableIdleTimeMillis" value="300000"></property>  
        <property name="numTestsPerEvictionRun" value="3"></property>  
        <property name="timeBetweenEvictionRunsMillis" value="60000"></property>   -->
        
        <property name="maxIdle" value="${redis.maxIdle}"></property>  
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"></property>  
        <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"></property>  
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"></property>
    </bean>  
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">  
        <property name="poolConfig" ref="jedisPoolConfig"></property>  
        <property name="hostName" value="${redis.hostName}"></property>  
        <property name="port" value="${redis.port}"></property>  
        <property name="timeout" value="${redis.timeout}"></property>  
        <property name="usePool" value="${redis.usePool}"></property>  
    </bean>  
    <bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
        <property name="connectionFactory" ref="jedisConnectionFactory"></property>  
        <property name="keySerializer">  
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>  
        </property>  
        <property name="valueSerializer">  
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
        </property>  
    </bean>  
</beans>  

3)、applicationContext.xml

  spring的总配置文件,在里面假如一下的代码

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreResourceNotFound" value="true" />
        <property name="locations">
            <list>
                
                <value>classpath*:/META-INF/config/redis.properties</value>
            </list>
        </property>
    </bean>

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

4)、web。xml

  设置spring的总配置文件在项目启动时加载

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/META-INF/applicationContext.xml</param-value><!--  -->
    </context-param>

5)、redis缓存工具类

ValueOperations  ——基本数据类型和实体类的缓存
ListOperations     ——list的缓存
SetOperations    ——set的缓存

HashOperations  Map的缓存

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

@Service
public class RedisCacheUtil<T>
{

    
    @Autowired @Qualifier("jedisTemplate")
    public RedisTemplate redisTemplate;
    

    
    /**
     * 缓存基本的对象,Integer、String、实体类等
     * @param key    缓存的键值
     * @param value    缓存的值
     * @return        缓存的对象
     */
    public <T> ValueOperations<String,T> setCacheObject(String key,T value)
    {
        
        ValueOperations<String,T> operation = redisTemplate.opsForValue(); 
        operation.set(key,value);
        return operation;
    }
    
    /**
     * 获得缓存的基本对象。
     * @param key        缓存键值
     * @param operation
     * @return            缓存键值对应的数据
     */
    public <T> T getCacheObject(String key/*,ValueOperations<String,T> operation*/)
    {
        ValueOperations<String,T> operation = redisTemplate.opsForValue(); 
        return operation.get(key);
    }
    
    /**
     * 缓存List数据
     * @param key        缓存的键值
     * @param dataList    待缓存的List数据
     * @return            缓存的对象
     */
    public <T> ListOperations<String, T> setCacheList(String key,List<T> dataList)
    {
        ListOperations listOperation = redisTemplate.opsForList();
        if(null != dataList)
        {
            int size = dataList.size();
            for(int i = 0; i < size ; i ++)
            {
                
                listOperation.rightPush(key,dataList.get(i));
            }
        }
        
        return listOperation;
    }
    
    /**
     * 获得缓存的list对象
     * @param key    缓存的键值
     * @return        缓存键值对应的数据
     */
    public <T> List<T> getCacheList(String key)
    {
        List<T> dataList = new ArrayList<T>();
        ListOperations<String,T> listOperation = redisTemplate.opsForList();
        Long size = listOperation.size(key);
        
        for(int i = 0 ; i < size ; i ++)
        {
            dataList.add((T) listOperation.leftPop(key));
        }
        
        return dataList;
    }
    
    /**
     * 缓存Set
     * @param key        缓存键值
     * @param dataSet    缓存的数据
     * @return            缓存数据的对象
     */
    public <T> BoundSetOperations<String,T> setCacheSet(String key,Set<T> dataSet)
    {
        BoundSetOperations<String,T> setOperation = redisTemplate.boundSetOps(key);    
        /*T[] t = (T[]) dataSet.toArray();
             setOperation.add(t);*/
        
        
        Iterator<T> it = dataSet.iterator();
        while(it.hasNext())
        {
            setOperation.add(it.next());
        }
        
        return setOperation;
    }
    
    /**
     * 获得缓存的set
     * @param key
     * @param operation
     * @return
     */
    public Set<T> getCacheSet(String key/*,BoundSetOperations<String,T> operation*/)
    {
        Set<T> dataSet = new HashSet<T>();
        BoundSetOperations<String,T> operation = redisTemplate.boundSetOps(key);    
        
        Long size = operation.size();
        for(int i = 0 ; i < size ; i++)
        {
            dataSet.add(operation.pop());
        }
        return dataSet;
    }
    
    /**
     * 缓存Map
     * @param key
     * @param dataMap
     * @return
     */
    public <T> HashOperations<String,String,T> setCacheMap(String key,Map<String,T> dataMap)
    {
        
        HashOperations hashOperations = redisTemplate.opsForHash();
        if(null != dataMap)
        {
            
            for (Map.Entry<String, T> entry : dataMap.entrySet()) {  
                  
                /*System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  */
                hashOperations.put(key,entry.getKey(),entry.getValue());
            } 
            
        }
        
        return hashOperations;
    }
    
    /**
     * 获得缓存的Map
     * @param key
     * @param hashOperation
     * @return
     */
    public <T> Map<String,T> getCacheMap(String key/*,HashOperations<String,String,T> hashOperation*/)
    {
        Map<String, T> map = redisTemplate.opsForHash().entries(key);
        /*Map<String, T> map = hashOperation.entries(key);*/
        return map;
    }
    
    
    
    
    
    
    
    /**
     * 缓存Map
     * @param key
     * @param dataMap
     * @return
     */
    public <T> HashOperations<String,Integer,T> setCacheIntegerMap(String key,Map<Integer,T> dataMap)
    {
        HashOperations hashOperations = redisTemplate.opsForHash();
        if(null != dataMap)
        {
            
            for (Map.Entry<Integer, T> entry : dataMap.entrySet()) {  
                  
                /*System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  */
                hashOperations.put(key,entry.getKey(),entry.getValue());
            } 
            
        }
        
        return hashOperations;
    }
    
    /**
     * 获得缓存的Map
     * @param key
     * @param hashOperation
     * @return
     */
    public <T> Map<Integer,T> getCacheIntegerMap(String key/*,HashOperations<String,String,T> hashOperation*/)
    {
        Map<Integer, T> map = redisTemplate.opsForHash().entries(key);
        /*Map<String, T> map = hashOperation.entries(key);*/
        return map;
    }
}
    

6)、测试

  这里测试我是在项目启动的时候到数据库中查找出国家和城市的数据,进行缓存,之后将数据去出

6.1  项目启动时缓存数据

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;

import com.test.model.City;
import com.test.model.Country;
import com.zcr.test.User;

/*
 * 监听器,用于项目启动的时候初始化信息
 */
@Service
public class StartAddCacheListener implements ApplicationListener<ContextRefreshedEvent>
{
    //日志
    private final Logger log= Logger.getLogger(StartAddCacheListener.class);
    
    @Autowired
    private RedisCacheUtil<Object> redisCache;
    
    @Autowired
    private BrandStoreService brandStoreService;
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent  event) 
    {
        //spring 启动的时候缓存城市和国家等信息
        if(event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext"))
        {
            System.out.println("


_________

缓存数据 

 ________



");
            List<City> cityList = brandStoreService.selectAllCityMessage();
            List<Country> countryList = brandStoreService.selectAllCountryMessage();
            
            Map<Integer,City> cityMap = new HashMap<Integer,City>();
            
            Map<Integer,Country> countryMap = new HashMap<Integer, Country>();
            
            int cityListSize = cityList.size();
            int countryListSize = countryList.size();
            
            for(int i = 0 ; i < cityListSize ; i ++ )
            {
                cityMap.put(cityList.get(i).getCity_id(), cityList.get(i));
            }
            
            for(int i = 0 ; i < countryListSize ; i ++ )
            {
                countryMap.put(countryList.get(i).getCountry_id(), countryList.get(i));
            }
            
            redisCache.setCacheIntegerMap("cityMap", cityMap);
            redisCache.setCacheIntegerMap("countryMap", countryMap);
        }
    }
    
}

6.2  获取缓存数据

    @Autowired
    private RedisCacheUtil<User> redisCache;

    @RequestMapping("testGetCache")
    public void testGetCache()
    {
        /*Map<String,Country> countryMap = redisCacheUtil1.getCacheMap("country");
        Map<String,City> cityMap = redisCacheUtil.getCacheMap("city");*/
        Map<Integer,Country> countryMap = redisCacheUtil1.getCacheIntegerMap("countryMap");
        Map<Integer,City> cityMap = redisCacheUtil.getCacheIntegerMap("cityMap");
        
        for(int key : countryMap.keySet())
        {
            System.out.println("key = " + key + ",value=" + countryMap.get(key));
        }
        
        System.out.println("------------city");
        for(int key : cityMap.keySet())
        {
            System.out.println("key = " + key + ",value=" + cityMap.get(key));
        }
    }     

  由于Spring在配置文件中配置的bean默认是单例的,所以只需要通过Autowired注入,即可得到原先的缓存类。

  致谢:感谢您的阅读!

免责声明:文章转载自《spring + redis 实现数据的缓存》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇实现CI/CDk8s高可用集群搭建总结以及部署API到k8sc#实现冒泡、快速、选择和插入排序算法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于Android中的三级缓存

三级缓存的提出就是为了提升用户体验。当我们第一次打开应用获取图片时,先到网络去下载图片,然后依次存入内存缓存,磁盘缓存,当我们再一次需要用到刚才下载的这张图片时,就不需要再重复的到网络上去下载,直接可以从内存缓存和磁盘缓存中找,由于内存缓存速度较快,我们优先到内存缓存中寻找该图片,如果找到则运用,如果没有找到(内存缓存大小有限),那么我们再到磁盘缓存中去找...

使用redis作为消息队列的用法

背景 最近项目有个需求需要动态更新规则,当时脑中想到的第一个方案是利用zk的监听机制,管理人员更新完规则将状态写入zk,集群中的机器监听zk的状态,当有状态变更后,集群中的机器开始拉取最新的配置。但由于公司技术选型,没有专门搭建zk集群,因此也不可能为这一个小需求去搭建zk集群。图为使用zk监听状态变化的流程。 最后只好退而求其次,想到了使用redis的...

C#使用SmtpClient发送邮件

原理:  例如A使用163邮箱发送邮件给B(qq邮箱)。首先A会把邮件通过SMTP(Simple Mail Transfer Protocol)协议传输到163的Smtp服务器上,163的Smtp服务器会根据B的邮箱账号,把邮件通过Smtp协议发给QQ邮箱的Smtp服务器。QQ的Smtp服务器接收到邮件消息后会将之存储在QQ邮箱的邮件存储设备上。当B登陆Q...

如何统计代码行执行的时间?

1.问题 请计算下列代码执行所耗费的时间,给出通用的解决方法? List<Int32> myList=new List<Int32>(); for(Int32 i=0;i<ICount;i++) { myList.Add(i); } 2.解决方法 using (OperationTimer op=new OperationT...

python服务器环境搭建——安装相关软件

在上一篇我们在本地的虚拟服务器上安装好CentOS7后,我们的python web服务、自定义的python service或python脚本需要在服务器上运行,还需要在服务器安装各种相关的软件才行,一般来说,想要实现自动化部署需求,还需要安装nginx、svn、uwsgi、python3.0(系统自带python2.7.5)、supervisor、pos...

Spring Security 实战干货:玩转自定义登录

文章目录 1. 前言 2. form 登录的流程 3. Spring Security 中的登录 4. HttpSecurity 中的 form 表单登录 4.1 FormLoginConfigurer 5. Spring Security 聚合登录 实战 5.1 简单需求 6. 多种登录方式的简单实现 6.1 登录方式定义 6.2 定义前置处理器...