Redis 应用示例

来自Wikioe
跳到导航 跳到搜索


示例一


(redis的客户端jedis常用)

  1. 在项目中配置 Redis:(单机版、集群版)
    1. 配置文件:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
          xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
          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-4.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
          <!-- 连接池配置 -->
          <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
              <!-- 最大连接数 -->
              <property name="maxTotal" value="30" />
              <!-- 最大空闲连接数 -->
              <property name="maxIdle" value="10" />
              <!-- 每次释放连接的最大数目 -->
              <property name="numTestsPerEvictionRun" value="1024" />
              <!-- 释放连接的扫描间隔(毫秒) -->
              <property name="timeBetweenEvictionRunsMillis" value="30000" />
              <!-- 连接最小空闲时间 -->
              <property name="minEvictableIdleTimeMillis" value="1800000" />
              <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
              <property name="softMinEvictableIdleTimeMillis" value="10000" />
              <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
              <property name="maxWaitMillis" value="1500" />
              <!-- 在获取连接的时候检查有效性, 默认false -->
              <property name="testOnBorrow" value="true" />
              <!-- 在空闲时检查有效性, 默认false -->
              <property name="testWhileIdle" value="true" />
              <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
              <property name="blockWhenExhausted" value="false" />
          </bean>  
          <!-- jedis客户端单机版 -->
          <bean id="redisClient" class="redis.clients.jedis.JedisPool">
              <constructor-arg name="host" value="192.168.146.131"></constructor-arg>
              <constructor-arg name="port" value="6379"></constructor-arg>
              <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
          </bean>
          <bean id="jedisClient" class="com.taotao.rest.dao.impl.JedisClientSingle"/>
           
           
          <!-- jedis集群版配置 -->
          <!-- <bean id="redisClient" class="redis.clients.jedis.JedisCluster">
              <constructor-arg name="nodes">
                  <set>
                      <bean class="redis.clients.jedis.HostAndPort">
                          <constructor-arg name="host" value="192.168.25.153"></constructor-arg>
                          <constructor-arg name="port" value="7001"></constructor-arg>
                      </bean>
                      <bean class="redis.clients.jedis.HostAndPort">
                          <constructor-arg name="host" value="192.168.25.153"></constructor-arg>
                          <constructor-arg name="port" value="7002"></constructor-arg>
                      </bean>
                      <bean class="redis.clients.jedis.HostAndPort">
                          <constructor-arg name="host" value="192.168.25.153"></constructor-arg>
                          <constructor-arg name="port" value="7003"></constructor-arg>
                      </bean>
                      <bean class="redis.clients.jedis.HostAndPort">
                          <constructor-arg name="host" value="192.168.25.153"></constructor-arg>
                          <constructor-arg name="port" value="7004"></constructor-arg>
                      </bean>
                      <bean class="redis.clients.jedis.HostAndPort">
                          <constructor-arg name="host" value="192.168.25.153"></constructor-arg>
                          <constructor-arg name="port" value="7005"></constructor-arg>
                      </bean>
                      <bean class="redis.clients.jedis.HostAndPort">
                          <constructor-arg name="host" value="192.168.25.153"></constructor-arg>
                          <constructor-arg name="port" value="7006"></constructor-arg>
                      </bean>
                  </set>
              </constructor-arg>
              <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
          </bean>
          <bean id="jedisClientCluster" class="com.taotao.rest.dao.impl.JedisClientCluster"></bean> -->
      </beans>
      
    2. JedisClient 接口定义:
      public interface JedisClient{
          String get(String key);  // 读取数据
          String set(String key, String value);  // 向Redis写入数据
          String hget(String hkey, String value);  // 获取存储结构是hashmap类型的操作
          Long hset(String key, String field, String value);
          Long incr(String key);
          Long expire(String key, int seconds);  // 设置生存时间
          Long ttl(String key);
          Long del(String key);  // 删除数据
          Long hdel(String hkey, String key);
          Boolean exists(String key);
      }
      
    3. 接口实现(单机版):
      package com.taotao.rest.dao.impl;
       
      import org.springframework.beans.factory.annotation.Autowired;
      import com.taotao.rest.dao.JedisClient;
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
       
      public class JedisClientSingle implements JedisClient{
          @Autowired
          private JedisPool jedisPool;
           
          @Override
          public String get(String key) {
              Jedis jedis = jedisPool.getResource();
              String string = jedis.get(key);
              jedis.close();
              return string;
          }
       
          @Override
          public String set(String key, String value) {
              Jedis jedis = jedisPool.getResource();
              String string = jedis.set(key, value);
              jedis.close();
              return string;
          }
       
          @Override
          public String hget(String hkey, String key) {
              Jedis jedis = jedisPool.getResource();
              String string = jedis.hget(hkey, key);
              jedis.close();
              return string;
          }
       
          @Override
          public long hset(String hkey, String key, String value) {
              Jedis jedis = jedisPool.getResource();
              Long result = jedis.hset(hkey, key, value);
              jedis.close();
              return result;
          }
       
          @Override
          public long incr(String key) {
              Jedis jedis = jedisPool.getResource();
              Long result = jedis.incr(key);
              jedis.close();
              return result;
          }
       
          @Override
          public long expire(String key, int second) {
              Jedis jedis = jedisPool.getResource();
              Long result = jedis.expire(key, second);
              jedis.close();
              return result;
          }
       
          @Override
          public long ttl(String key) {
              Jedis jedis = jedisPool.getResource();
              Long result = jedis.ttl(key);
              jedis.close();
              return result;
          }
       
          @Override
          public long del(String key) {
              Jedis jedis = jedisPool.getResource();
              Long result = jedis.del(key);
              jedis.close();
              return result;
          }
       
          @Override
          public long hdel(String hkey, String key) {
              Jedis jedis = jedisPool.getResource();
              Long result = jedis.hdel(hkey, key);
              jedis.close();
              return result;
          }
      }
      
    4. 接口实现(集群版):
      package com.taotao.rest.dao.impl;
       
      import org.springframework.beans.factory.annotation.Autowired;
      import com.taotao.rest.dao.JedisClient;
      import redis.clients.jedis.JedisCluster;
      
      public class JedisClientCluster implements JedisClient {
          @Autowired
          private JedisCluster jedisCluster;
           
          @Override
          public String get(String key) {
              return jedisCluster.get(key);
          }
       
          @Override
          public String set(String key, String value) {
              return jedisCluster.set(key, value);
          }
       
          @Override
          public String hget(String hkey, String key) {
              return jedisCluster.hget(hkey, key);
          }
       
          @Override
          public long hset(String hkey, String key, String value) {
              return jedisCluster.hset(hkey, key, value);
          }
       
          @Override
          public long incr(String key) {
              return jedisCluster.incr(key);
          }
       
          @Override
          public long expire(String key, int second) {
              return jedisCluster.expire(key, second);
          }
       
          @Override
          public long ttl(String key) {
              return jedisCluster.ttl(key);
          }
       
          @Override
          public long del(String key) {
               
              return jedisCluster.del(key);
          }
       
          @Override
          public long hdel(String hkey, String key) {
               
              return jedisCluster.hdel(hkey, key);
          }
      }
      
  2. 业务逻辑使用 Redis:
    Redis 作为缓存的作用就是减少对数据库的访问压力,当我们访问一个数据的时候,首先我们从 Redis 中查看是否有该数据,如果没有,则从数据库中读取,将从数据库中读取的数据存放到缓存中,下次再访问同样的数据的是,还是先判断 Redis 中是否存在该数据,如果有,则从缓存中读取,不访问数据库了。
    示例,根据内容分类 id 访问内容:
    package com.taotao.rest.service.impl;
     
    import java.util.ArrayList;
    import java.util.List;
     
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
     
    import com.taotao.commonEntity.JsonUtils;
    import com.taotao.commonEntity.TaotaoResult;
    import com.taotao.mapper.TbContentMapper;
    import com.taotao.pojo.TbContent;
    import com.taotao.pojo.TbContentExample;
    import com.taotao.pojo.TbContentExample.Criteria;
    import com.taotao.rest.dao.JedisClient;
    import com.taotao.rest.service.ContentService;
     
    import redis.clients.jedis.Jedis;
    //首页大广告位的获取服务层信息
    @Service
    public class ContentServiceImpl implements ContentService {
        @Value("${CONTENTCATEGORYID}")
        private String CONTENTCATEGORYID;
        @Autowired
        private TbContentMapper contentMapper;
        @Autowired
        private JedisClient jedisClient;
         
        @Override
        public List<TbContent> getContentList(Long categoryId) {
            /*
            一般第一次访问的时候先从数据库读取数据,然后将数据写入到缓存,再次访问同一内容的时候就从缓存中读取,如果缓存中没有则从数据库中读取
            所以我们添加缓存逻辑的时候,从数据库中将内容读取出来之后,先set入缓存,然后再从缓存中添加读取行为,如果缓存为空则从数据库中进行读取
            */
            // 从缓存获取值
            String getData = jedisClient.hget(CONTENTCATEGORYID, categoryId+"");
            if (!StringUtils.isBlank(getData)) {
                List<TbContent> resultList= JsonUtils.jsonToList(getData, TbContent.class);
                return resultList; 
            }
            // 缓存未命中:
            // 1、从数据库获取值
            TbContentExample example=new TbContentExample();
            Criteria criteria = example.createCriteria();
            criteria.andCategoryIdEqualTo(categoryId);
            List<TbContent> list = contentMapper.selectByExample(example);
            // 2、向缓存放入值
            String jsonData = JsonUtils.objectToJson(list);
            jedisClient.hset(CONTENTCATEGORYID, categoryId+"",jsonData);
            return list;
        }
    }
    
  3. 缓存同步
    当我们后台数据库中内容修改之后,因为缓存中的内容没有修改,我们访问的时候都是先访问缓存,所以即使数据库中的内容修改了,但是页面的显示还是不会改变的。因为缓存没有更新,所以这就涉及到“缓存同步”的问题:即数据库修改了内容与缓存中对应的内容同步。
    缓存同步的原理:就是将 Redis 中的 key 进行删除,下次访问的时候,Redis 中没有改数据,则从 DB 进行查询,再次更新到 Redis 中。
    实现步骤如下:
    1. “缓存同步服务”接口:【?】
      public interface JedisSynService{
          public TaobaoResult synContent()
      }
      
    2. “缓存同步服务”实现:
      public class JedisSynServiceImpl implements JedisSynService{
          @Autowired
          private JedisCient jedisCient;
          @Value{"${CONTENTCATEGORYID}"}
          private String CONTENTCATEGORYID;
          
          @Override
          public TaobaoResult synContent(Long categoryId){
              // 缓存同步的实现:实现原理就是将 Redis 中的 key 进行删除,下次访问的时候,Redis 中没有改数据,则从 DB 进行查询,再次更新到 Redis 中
              jedisCient.hdel(CONTENTCATEGORYID, categoryId+"");
              return TaobaoResult.ok();
          }
      }
      
    3. “缓存同步服务”控制器:
      @RestController
      @RequestMapping("/cache/syn")
      public class JedisSynController{
          @Autowired
          private JedisSynService jedisSynService;
          @RequestMapping("/content/{categoryId}")
          public TaobaoResult synContent(@PathVariable Long categoryId){
              TaobaoResult result = jedisSynService.synContent(categoryId);
              return result;
          }
      }
      
    4. 业务中实现“缓存同步”:
      只需要在后台进行 CRUD 的地方添加调用该缓存同步的服务即可;【???】
          public TaobaoResult editContent(TbContent tbContent){
              TbContent content = new TbContent();
              content.setId(tbContent.getId());
              content.setCategoryId(tbContent.getCategoryId());
              content.setTitle(tbContent.getTitle());
              content.setSubTitle(tbContent.getSubTitle());
              content.setTitleDesc(tbContent.getTitleDesc());
              content.setUrl(tbContent.getUrl());
              content.setPic(tbContent.getPic());
              content.setPic2(tbContent.getPic2());
              content.setContent(tbContent.getContent());
              content.setCreated(new Date());
              content.setUpdated(new Date());
              // 调用失败,服务层是没有问题的,但服务的调用有问题
              HttpClientUtil.doGet(BASE_REST_URL+CACHE_SYN_URL+content.getCategoryId());
              return TaobaoResult.ok();
          }
      
      • 缓存同步除了查询是没有涉及到同步问题,增加删除修改都会涉及到同步问题。

redis客户端jedis的使用:

Redis 应用示例:redis的使用.png

示例二

把 Redis 整合到 JavaWeb 项目中,向业务逻辑中添加缓存。


  1. 常用的操作 Redis 的方法提取出一个接口,分别对应单机版和集群版创建两个实现类。
    1. Redis 接口定义:
      package cn.e3mall.common.jedis;
      import java.util.List;
      public interface JedisClient {
      	String set(String key, String value);
      	String get(String key);
      	Boolean exists(String key);
      	Long expire(String key, int seconds);
      	Long ttl(String key);
      	Long incr(String key);
      	Long hset(String key, String field, String value);
      	String hget(String key, String field);
      	Long hdel(String key, String... field);
      	Boolean hexists(String key, String field);
      	List<String> hvals(String key);
      	Long del(String key);
      }
      
      Redis 接口实现(单机):
      package cn.e3mall.common.jedis;
      import java.util.List;
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
      public class JedisClientPool implements JedisClient {
      	private JedisPool jedisPool;
      	public JedisPool getJedisPool() {
      		return jedisPool;
      	}
      	public void setJedisPool(JedisPool jedisPool) {
      		this.jedisPool = jedisPool;
      	}
          
      	@Override
      	public String set(String key, String value) {
      		Jedis jedis = jedisPool.getResource();
      		String result = jedis.set(key, value);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public String get(String key) {
      		Jedis jedis = jedisPool.getResource();
      		String result = jedis.get(key);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Boolean exists(String key) {
      		Jedis jedis = jedisPool.getResource();
      		Boolean result = jedis.exists(key);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Long expire(String key, int seconds) {
      		Jedis jedis = jedisPool.getResource();
      		Long result = jedis.expire(key, seconds);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Long ttl(String key) {
      		Jedis jedis = jedisPool.getResource();
      		Long result = jedis.ttl(key);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Long incr(String key) {
      		Jedis jedis = jedisPool.getResource();
      		Long result = jedis.incr(key);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Long hset(String key, String field, String value) {
      		Jedis jedis = jedisPool.getResource();
      		Long result = jedis.hset(key, field, value);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public String hget(String key, String field) {
      		Jedis jedis = jedisPool.getResource();
      		String result = jedis.hget(key, field);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Long hdel(String key, String... field) {
      		Jedis jedis = jedisPool.getResource();
      		Long result = jedis.hdel(key, field);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Boolean hexists(String key, String field) {
      		Jedis jedis = jedisPool.getResource();
      		Boolean result = jedis.hexists(key, field);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public List<String> hvals(String key) {
      		Jedis jedis = jedisPool.getResource();
      		List<String> result = jedis.hvals(key);
      		jedis.close();
      		return result;
      	}
      	@Override
      	public Long del(String key) {
      		Jedis jedis = jedisPool.getResource();
      		Long result = jedis.del(key);
      		jedis.close();
      		return result;
      	}
      }
      
      Redis 接口实现(集群):
      package cn.e3mall.common.jedis;
      import java.util.List;
      import redis.clients.jedis.JedisCluster;
      public class JedisClientCluster implements JedisClient {
      	private JedisCluster jedisCluster;
      	public JedisCluster getJedisCluster() {
      		return jedisCluster;
      	}
      	public void setJedisCluster(JedisCluster jedisCluster) {
      		this.jedisCluster = jedisCluster;
      	}
          
      	@Override
      	public String set(String key, String value) {
      		return jedisCluster.set(key, value);
      	}
      	@Override
      	public String get(String key) {
      		return jedisCluster.get(key);
      	}
      	@Override
      	public Boolean exists(String key) {
      		return jedisCluster.exists(key);
      	}
      	@Override
      	public Long expire(String key, int seconds) {
      		return jedisCluster.expire(key, seconds);
      	}
      	@Override
      	public Long ttl(String key) {
      		return jedisCluster.ttl(key);
      	}
      	@Override
      	public Long incr(String key) {
      		return jedisCluster.incr(key);
      	}
      	@Override
      	public Long hset(String key, String field, String value) {
      		return jedisCluster.hset(key, field, value);
      	}
      	@Override
      	public String hget(String key, String field) {
      		return jedisCluster.hget(key, field);
      	}
      	@Override
      	public Long hdel(String key, String... field) {
      		return jedisCluster.hdel(key, field);
      	}
      	@Override
      	public Boolean hexists(String key, String field) {
      		return jedisCluster.hexists(key, field);
      	}
      	@Override
      	public List<String> hvals(String key) {
      		return jedisCluster.hvals(key);
      	}
      	@Override
      	public Long del(String key) {
      		return jedisCluster.del(key);
      	}
      }
      
    2. 配置文件:“applicationContext-redis.xml”
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
      	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
      	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-4.2.xsd
      	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
      	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
      	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
      	
      	<!-- 连接redis单机版 -->
      	<bean id="jedisClientPool" class="cn.e3mall.common.jedis.JedisClientPool">
      		<property name="jedisPool" ref="jedisPool"></property>
      	</bean>
      	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
      		<constructor-arg name="host" value="115.159.126.205"/>
      		<constructor-arg name="port" value="6379"/>
      	</bean>
          
      	<!-- 连接redis集群 -->
      	<!-- <bean id="jedisClientCluster" class="cn.e3mall.common.jedis.JedisClientCluster">
      		<property name="jedisCluster" ref="jedisCluster"/>
      	</bean>
      	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
      		<constructor-arg name="nodes">
      			<set>
      				<bean class="redis.clients.jedis.HostAndPort">
      					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
      					<constructor-arg name="port" value="7001"></constructor-arg>
      				</bean> 
      				<bean class="redis.clients.jedis.HostAndPort">
      					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
      					<constructor-arg name="port" value="7002"></constructor-arg>
      				</bean> 
      				<bean class="redis.clients.jedis.HostAndPort">
      					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
      					<constructor-arg name="port" value="7003"></constructor-arg>
      				</bean> 
      				<bean class="redis.clients.jedis.HostAndPort">
      					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
      					<constructor-arg name="port" value="7004"></constructor-arg>
      				</bean> 
      				<bean class="redis.clients.jedis.HostAndPort">
      					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
      					<constructor-arg name="port" value="7005"></constructor-arg>
      				</bean> 
      				<bean class="redis.clients.jedis.HostAndPort">
      					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
      					<constructor-arg name="port" value="7006"></constructor-arg>
      				</bean> 
      			</set>
      		</constructor-arg>
      	</bean> -->
      </beans>
      
    3. 测试代码:
      @Test
      public void testJedisClient() throws Exception {
      	//初始化Spring容器
      	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
      	//从容器中获得JedisClient对象
      	JedisClient jedisClient = applicationContext.getBean(JedisClient.class);
      	jedisClient.set("first", "100");
      	String result = jedisClient.get("first");
      	System.out.println(result);						
      }
      
  2. 添加缓存:查询数据库之前先查询缓存。
    1. 查询到结果,直接响应结果。
    2. 查询不到(缓存中没有需要查询数据库):
      1. 把查询结果添加到缓存中。
      2. 返回结果。
    代码实现(服务层)
    	. . .
    	@Autowired
    	private JedisClient jedisClient;
    	. . .
        
        @Value("${CONTENT_LIST}")
    	private String CONTENT_LIST;
    	
    	@Override
    	public E3Result addContent(TbContent content) {
    		//将内容数据插入到内容表
    		content.setCreated(new Date());
    		content.setUpdated(new Date());
    		//插入到数据库
    		contentMapper.insert(content);
    		//缓存同步,删除缓存中对应的数据。
    		jedisClient.hdel(CONTENT_LIST, content.getCategoryId().toString());
    		return E3Result.ok();
    	}
    	. . .
        
        @Override
        public List<TbContent> getContentListByCid(long cid) {
    	    //查询缓存
    	    try {
    		    //如果缓存中有直接响应结果
    		    String json = jedisClient.hget(CONTENT_LIST, cid + "");
    		    if (StringUtils.isNotBlank(json)) {
    			    List<TbContent> list = JsonUtils.jsonToList(json,TbContent.class);
    			    System.out.println("从缓存中查出的数据");
    			    return list;
    		    }
    	    } catch (Exception e) {
    		    e.printStackTrace();
    	    }
            
    	    //缓存中没有,查询数据库
    	    TbContentExample example = new TbContentExample();
    	    Criteria criteria = example.createCriteria();
    	    //设置查询条件
    	    criteria.andCategoryIdEqualTo(cid);
    	    //执行查询
    	    List<TbContent> list = contentMapper.selectByExampleWithBLOBs(example);
    	    //把结果添加到缓存
    	    try {
    		    System.out.println("把结果添加到缓存");
    		    jedisClient.hset(CONTENT_LIST, cid + "", JsonUtils.objectToJson(list));
    	    } catch (Exception e) {
    		    e.printStackTrace();
    	    }
    	    return list;
        }
    
  • 热缓存:
    	@Override
    	public TbItem getItemById(long itemId) {
    		//获取商品添加缓存,不影业务响逻辑,try-catch
    		try {
    			System.out.println("缓存获取商品信息");
    			String json = jedisClient.get(REDIS_ITEM_PRE+":"+itemId+":BASE");
    			if(StringUtils.isNotBlank(json)) {
    				TbItem tbItem = JsonUtils.jsonToPojo(json,TbItem.class);
    				return tbItem;
    			}
    		}catch(Exception e) {
    			e.printStackTrace();
    		}
            
    		//缓存中没有,查询数据库
    		//根据主键查询
    		//TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);
    		TbItemExample example = new TbItemExample();
    		Criteria criteria = example.createCriteria();
    		//设置查询条件
    		criteria.andIdEqualTo(itemId);
    		//执行查询
    		List<TbItem> list = itemMapper.selectByExample(example);
    		if (list != null && list.size() > 0) {
    			//结果添加到缓存
    			try {
    				System.out.println("缓存添加商品信息");
    				jedisClient.set(REDIS_ITEM_PRE+":"+itemId+":BASE",JsonUtils.objectToJson(list.get(0)));
    				//设置过期时间(1个小时)
    				jedisClient.expire(REDIS_ITEM_PRE+":"+itemId+":BASE",TIEM_CACHE_EXPIRE);
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    			return list.get(0);
    		}
    		return null;
    	}
    

结果:

Redis 应用示例:执行结果.png
Redis 应用示例:缓存内容.png

Redis 中的数据:

{"itemId":1231490,"created":1425821627000,"updated":1425821627000,"itemDesc":"<table cellpadding=\"0\" cellspacing=\"0\" align=\"center\" border=\"0\" width=\"750\">  <tbody>    <tr>      <td height=\"51\" width=\"750\"><div style=\"PADDING-BOTTOM: 15px; LINE-HEIGHT: 1.5em; PADDING-LEFT: 15px; PADDING-RIGHT: 15px; FONT-FAMILY: '微软雅黑'; FONT-SIZE: 15px; PADDING-TOP: 15px\"><span style=\"color:#ff6666;\"><strong>温馨提示:</strong></span><strong>小米4联通版</strong>内置运营商软件,<strong>小米4官方联通版</strong>是无内置运营商软件的。</div></td>    </tr>  </tbody></table><div class=\"content_tpl\">    <div class=\"formwork_bt\" id=\"detail-tag-id-0\" name=\"detail-tag-id-0\" text=\"产品展示\">   <div class=\"formwork_bt_dz\">    <span>产品展示</span>    <span class=\"s2\">Products Exhibition</span>   </div>  </div> <table cellpadding=\"0\" cellspacing=\"6\" align=\"center\" border=\"0\" width=\"750\">  <tbody><tr>    <td><img src=\"http://img30.360buyimg.com/jgsq-productsoa/jfs/t346/347/1422821621/45195/e22eac9b/5439038bNa168d543.jpg\" alt=\"\" /></td>    <td><p class=\"formwork_titleleft\">小米手机4</p><p class=\"formwork_titleleft2\">依然出色性能用智能手机阅读、拍照、游戏甚至完成复杂艰巨的任务,这一切都依赖于快。每一代小米手机,都使用了当前先进的元器件。更快的处理器、更快的闪存、更快的相机和图像处理,支持更快的网络。集世界全新科技在一部5英寸大小的设备,只为让科技乐趣人人都可享用,生活正因此变得更加美好</p></td>  </tr></tbody></table>    <div class=\"formwork_bt\" id=\"detail-tag-id-2\" name=\"detail-tag-id-2\" text=\"产品信息\">   <div class=\"formwork_bt_dz\">    <span>产品信息</span>    <span class=\"s2\">Product Information</span>   </div>  </div> <div class=\"formwork\"><div class=\"formwork_titlecenter\">Qualcomm&reg; 骁龙? 801四核2.5GHz 处理器</div><div class=\"formwork_text\">高端手机处理器性能之王小米手机 4 采用了高通动力十足的骁龙801手机处理器,内含四个Krait 400 2.5GHz 处理核心。运算速度提升14%,性能更强大。它能出色地同时处理多个复杂任务。它的强大还体现在图像处理器速度较前代提升近一倍,这让拍照与录像都有了更多玩法和可能性。内含一个 Hexagon DSP 核心,专门以超低功耗运行电影、音乐、拍照等任务。这意味着在性能更强大的同时,手机续航都比以往更加持久耐用。</div></div><div class=\"formwork\"><div class=\"formwork_img\"><img src=\"http://img20.360buyimg.com/vc/jfs/t307/358/1403468763/249668/b4048162/54388804Na68f8ead.png\" alt=\"\" /></div></div><div class=\"formwork\"><div class=\"formwork_titlecenter\">Adreno 330 图形处理器</div><div class=\"formwork_text\">游戏机品质的3D渲染能力Adreno 330 图形处理器支持高级图形处理API,包括OpenGL ES 3.0、OpenCL、RenderscriptCompute和FlexRender 。它之所以能够快速渲染复杂的图形,得益于统一渲染架构及FlexRender 快速渲染技术。统一渲染架构能够根据所渲染的图形类型,动态调整其资源分配方式,像素和顶点渲染均可进行独立调节。FlexRender 技术可以直接或通过延迟渲染模式在图形像素间动态转换,从而帮助Adreno GPU更快速、更高效地渲染游戏图形。</div></div><div class=\"formwork\"><div class=\"formwork_img\"><img src=\"http://img20.360buyimg.com/vc/jfs/t352/350/1359939860/199186/e31d4b62/5438882fN8a00b5ac.png\" alt=\"\" /></div></div><div class=\"formwork\"><div class=\"formwork_titlecenter\">高色饱和度屏,84% NTSC色域</div><div class=\"formwork_text\">鲜艳度比 iPhone 5s 高17%小米手机4 采用了高色彩饱和度夏普/JDI屏幕,整体的色彩饱和度提升17%,令色彩表现力更加丰富。无论在小米手机4上面浏览图片、观看视频,或是使用精彩的App,都能为你呈现逼真的颜色效果。</div></div><div class=\"formwork\"><div class=\"formwork_img\"><img src=\"http://img20.360buyimg.com/vc/jfs/t292/303/1377649814/236958/cf633089/54388856N6b7e3293.png\" alt=\"\" /></div></div><table cellpadding=\"0\" cellspacing=\"6\" align=\"center\" border=\"0\" width=\"750\">  <tbody><tr>    <td><img src=\"http://img20.360buyimg.com/vc/jfs/t337/149/1399837173/112733/5916cfcd/54388886Neddc8729.png\" alt=\"\" /></td>    <td><p class=\"formwork_titleleft\">索尼高画质</p><p class=\"formwork_titleleft2\">最快0.3秒极速对焦如何用手机拍下转瞬即逝的美好瞬间?采用索尼 IMX 214 第二代 1300 万像素 Exmor RS? 堆栈式图像传感器,通过减少片上微透镜与感光二极管的距离,使其更容易集合光线。支持硬件更丰富、噪点更少的照片。6片镜头组采用了闭环式对焦技术,对焦最快至0.3秒,这比主流手机都快了两倍之多。它还具备手机上最大的F1.8大光圈,暗光更出色,背景虚化效果更加柔美。为了让拍摄具备更多便利和趣味,还可以使用魔术对焦功能,先拍照,回看时再选择焦点。不必苦练摄影技能,却可以用小米手机4拍出动人有趣的照片</p></td>  </tr></tbody></table><div class=\"formwork\"><div class=\"formwork_titlecenter\">支持最新4G LTE网络</div><div class=\"formwork_text\">用更快的方式上网、听音乐、看视频移动4G版支持最新中国移动4G(TDD-LTE)网络,下行峰值速率最高可达到132Mbps,上传的速度可达31Mbps。如此之快的传输速度几乎可满足对于无线应用的任何需要。当你外出旅行时,你可以用它随时随地观看在线高清视频,浏览网页或玩最流行的在线游戏,极速的4G网络速度可以带给你酣畅淋漓的使用体验。另可选购联通3G及电信3G版本。</div></div><div class=\"formwork\"><div class=\"formwork_img\"><img src=\"http://img20.360buyimg.com/vc/jfs/t322/260/1373090020/189626/610b2da/543888a1Ncd81c157.png\" alt=\"\" /></div></div><div class=\"formwork\"><div class=\"formwork_titlecenter\">用手机遥控电视、空调</div><div class=\"formwork_text\">配备红外发射器,支持2853款设备小米手机4 内置红外遥控功能,支持与红外接受设备的传输协议,可以通过专门为这一功能定制的小米遥控器App,遥控家里电视、空调等支持红外协议的家用电器。目前已支持2853款设备,更多设备不断更</div></div><div class=\"formwork\"><div class=\"formwork_img\"><img src=\"http://img20.360buyimg.com/vc/jfs/t343/265/1372124071/66786/5ee90d6e/543888d1N3d0c4330.png\" alt=\"\" /></div></div><div class=\"formwork\"><div class=\"formwork_titlecenter\">MIUI V5</div><div class=\"formwork_text\">全球24种语言版本,6500万用户好评如潮MIUI 针对原生 Android 深入系统底层优化,更流畅也更加省电。其次是好看,上千款原创主题,上万种搭配,让手机界面千变万化。更重要的是,它让你的生活更加方便。自动识别陌生电话,识别骚扰、诈骗电话。它还可以迅速找到你需要的生活服务,就连预约餐馆和医院挂号也能在系统中完成。</div></div><div class=\"formwork\"><div class=\"formwork_img\"><img src=\"http://img20.360buyimg.com/vc/jfs/t298/277/1374037756/194959/d1e9ee70/543888f1Na55c4785.png\" alt=\"\" /></div></div></div>"}
{"id":1231490,"title":"小米4 白色 联通3G手机","sellPoint":"卖完下柜!不锈钢金属边框,5英寸屏超窄边,骁龙四核2.5GHz处理器,3G RAM,1300W+800W摄像头!","price":199900,"num":99999,"barcode":null,"image":"https://g-search3.alicdn.com/img/bao/uploaded/i4/i3/TB1fyILc_mWBKNjSZFBXXXxUFXa.jpg_180x180.jpg_.webp","cid":560,"status":1,"created":1425821627000,"updated":1425821627000}