锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

spring结合redis如何实现数据的缓存

时间:2023-08-31 12:07:01 568236传感器盒srap

spring结合redis如何实现数据缓存


1. 实现目标
通过redis缓存数据字典表的数据。(目的不是加快查询,而是减轻数据库的负担)


2. 所需jar包


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

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文件

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">
























3)、applicationContext.xml
spring总配置文件:

ps.如果项目中有属性文件,则reis.properties文件必须这样写,因为spring是单例的

4)、web.xml

设置spring项目启动时加载了总配置文件,我在项目启动时写了一个监听器,将数据字典初始化为缓存

spring总配置文件:

contextConfigLocation
classpath:applicationContext.xml


监视器配置:

数据字典的初始化
com.sunyard.cims.listener.StartAddCacheListener

5)项目启动时加载的监听器 StartAddCacheListener类

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.context.event.ContextRefreshedEvent;
import com.sunyard.cims.controller.riskwarning.RiskWarningQueryController;
import com.sunyard.cims.service.riskwarning.RisWarningShowService;
import com.sunyard.cims.util.RedisCacheUtil;
import com.sunyard.framework.web.dao.CommonDao;
import com.sunyard.srap.entity.SrapBusDataDict;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import javax.persistence.criteria.CriteriaBuilder;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 缓存监听器,用于项目启动的时候初始化信息
 * @author yancb
 * 2017-11-01
 */
@Service
public class StartAddCacheListener  implements ApplicationListener {

private static Logger log = LoggerFactory.getLogger(StartAddCacheListener.class);

@Autowired
private RedisCacheUtil redisCache;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private CommonDao commonDao;

public void onApplicationEvent(ContextRefreshedEvent event) {
//spring 启动的时候缓存数据字典表信息
if(event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext"))
{

/**
 *数据字典表有重要的三个字段,一个是类型编号,例如1;一个是下拉框的隐藏值value,例如0,最后一个是下拉框的显示值name,例如男
 * 这里举个例子,我数据字典表存了一个性别的数据,那么数据库中有这样的两条记录:
 *  第一条   类型编号1  隐藏值0  显示值 ‘男’
 *  第二条   类型编号1  隐藏值1  显示值  ‘女’
 *  
 *  下面代码的思路就是先分组查询出数据字典表的所有类型编号,然后一个个遍历将每个类型编号的隐藏值和显示值都查出来,转为json格式,以
 *   key,value的形式存到缓存中
 */

List typeIdList = (List)commonDao
.findBySql("select item_type_id from srap_bus_data_dict group by item_type_id");
for(Integer type : typeIdList){
String key = "dict:type:"+type;//dict表示数据字典表,type表示类型,用这样来区分key

String sql = " SELECT item_value,item_name  FROM SRAP_BUS_DATA_DICT WHERE source_id = '0' and item_type_id = ?  order by item_value";
List> result = jdbcTemplate.query(sql, new Object[]{type}, new RowMapper>(){
public Map mapRow(ResultSet rs, int index)
throws SQLException {
Map row = new HashMap(2);
row.put("value", rs.getString("item_value"));
row.put("text", rs.getString("item_name"));
return row;
}
});
JSONArray arr = JSONArray.fromObject(result);
redisCache.setCacheString(key, arr.toString());
}
log.info("------------------------------------数据字典已加入到缓存中-----------------------------");
}
}
}

5)redis工具类

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

RedisCacheUtil类:

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
{

 @Autowired @Qualifier("jedisTemplate")
 public RedisTemplate redisTemplate;
 
 /**
  * 缓存基本的对象,Integer、String、实体类等
  * @param key 缓存的键值
  * @param value 缓存的值
  * @return  缓存的对象
  */
 public ValueOperations setCacheObject(String key,T value)
 {
  
  ValueOperations operation = redisTemplate.opsForValue(); 
  operation.set(key,value);
  return operation;
 }
 
 /**
  * 获得缓存的基本对象。
  * @param key  缓存键值
  * @param operation
  * @return   缓存键值对应的数据
  */
 public T getCacheObject(String key/*,ValueOperations operation*/)
 {
  ValueOperations operation = redisTemplate.opsForValue(); 
  return operation.get(key);
 }
 
 /**
  * 缓存List数据
  * @param key  缓存的键值
  * @param dataList 待缓存的List数据
  * @return   缓存的对象
  */
 public ListOperations setCacheList(String key,List 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 List getCacheList(String key)
 {
  List dataList = new ArrayList();
  ListOperations 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 BoundSetOperations setCacheSet(String key,Set dataSet)
 {
  BoundSetOperations setOperation = redisTemplate.boundSetOps(key); 
  /*T[] t = (T[]) dataSet.toArray();
    setOperation.add(t);*/
  
  Iterator it = dataSet.iterator();
  while(it.hasNext())
  {
   setOperation.add(it.next());
  }
  
  return setOperation;
 }
 
 /**
  * 获得缓存的set
  * @param key
  * @param operation
  * @return
  */
 public Set getCacheSet(String key/*,BoundSetOperations operation*/)
 {
  Set dataSet = new HashSet();
  BoundSetOperations 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 HashOperations setCacheMap(String key,Map dataMap)
 {
  
  HashOperations hashOperations = redisTemplate.opsForHash();
  if(null != dataMap)
  {
   
   for (Map.Entry 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 Map getCacheMap(String key/*,HashOperations hashOperation*/)
 {
  Map map = redisTemplate.opsForHash().entries(key);
  /*Map map = hashOperation.entries(key);*/
  return map;
 }
 
 /**
  * 缓存Map
  * @param key
  * @param dataMap
  * @return
  */
 public HashOperations setCacheIntegerMap(String key,Map dataMap)
 {
  HashOperations hashOperations = redisTemplate.opsForHash();
  if(null != dataMap)
  {
   for (Map.Entry 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 Map getCacheIntegerMap(String key/*,HashOperations hashOperation*/)
 {
  Map map = redisTemplate.opsForHash().entries(key);
  /*Map map = hashOperation.entries(key);*/
  return map;
 }
 
 
/**
  * 重新刷新缓存
  * @param itemTypeId
  */
 public void refreshCache(Integer itemTypeId){

    commonDao.flush();

    String key = "dict:type:"+itemTypeId;//dict表示数据字典表,type表示类型,用这样来区分key

    String sql = " SELECT item_value,item_name  FROM SRAP_BUS_DATA_DICT WHERE source_id = '0' and item_type_id = ?  order by item_value";
    List> result = jdbcTemplate.query(sql, new Object[]{itemTypeId}, new RowMapper>(){
     public Map mapRow(ResultSet rs, int index)
             throws SQLException {
      Map row = new HashMap(2);
      row.put("value", rs.getString("item_value"));
      row.put("text", rs.getString("item_name"));
      return row;
     }
    });
    if(result.size() == 0){
       redisTemplate.delete(key);//删除的时候如果取到list为空,表示该type已经没值了,那么删除key
    }else{
      JSONArray arr = JSONArray.fromObject(result);
      setCacheString(key, arr.toString());
    }
 }

 public void setCacheString(String key, String value){
  redisTemplate.opsForValue().set(key, value);
 }

 public String getCacheString(String key){
    Object value = redisTemplate.opsForValue().get(key);
    if(value != null)
     return value.toString();
    return "";
 }
}

6.页面下拉框获取缓存中数据

/**
* 取得本级业务数据字典数据(下拉框)  展示形式为 text
*/
public JsonData getDictTextOnly(PaginationBeanParam param, Integer itemTypeId, String IsReport) throws Exception{

String key = "dict:type:"+itemTypeId;
String jsonStr = redisCache.getCacheString(key);
JSONArray jsonArray = JSONArray.fromObject(jsonStr);
//  List> result = JSONArray.toList(jsonArray, HashMap.class);
List> result = (List>) JSONArray.toCollection(jsonArray,HashMap.class);
Map row = new HashMap();
if(IsReport!=null && "1".equals(IsReport)){
row.put("value", "-1");
row.put("text", "--选择全部--");
}else{
row.put("value", "");
row.put("text", "--请选择--");
}
result.add(0,row);

JsonData data = AbstractPaginationBeanHelperTemplate.getJsonData(param, result);
data.setCount(Long.valueOf(result.size()));
data.setSuccess(true);
return data;
}

7.  测试

这里测试我是获取某个类型的值

String str = redisCache.getCacheString("dict:type:1");

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章