精华内容
下载资源
问答
  • spring整合redis做缓存用注解实现的完整例子,带jar包,可以直接运行
  • 主要给大家介绍了关于Spring Boot中使用Redis做缓存的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
  • SpringBoot集成Redis和配置Redis做缓存

    万次阅读 多人点赞 2019-06-21 16:06:43
    Redis是一个开源的、高性能的、基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同场景下的缓存与存储需求,直观的存储结构使得通过程序交互十分简单。 Redis数据库中所有数据都存储在内存中,由于...

    Redis介绍

    Redis是一个开源的、高性能的、基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同场景下的缓存与存储需求,直观的存储结构使得通过程序交互十分简单。
    Redis数据库中所有数据都存储在内存中,由于内存的读写速度远快于硬盘,因此Redis在性能上对比其他基于硬盘存储的数据库有非常明显的优势,而且Redis提供了对持久化的支持,即可以将内存中的数据异步写入到硬盘中,且不影响继续提供服务。
    Redis提供了丰富的功能,越来愈多的人将其用作缓存、队列系统等。
    Redis是开源的,良好的开发氛围和严谨的版本发布机制使得Redis的版本非常稳定可靠,如此多的公司在项目中使用了Redis也可以印证这一点。

    本文内容分两块,配置文件分别单独记录

    SpringBoot 2.x版本项目配置Redis数据库及使用

    1.项目pom文件引入Redis依赖

    <!-- kaptcha -->  
    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    2.配置application.properties

    # Redis数据库索引(默认为0)
    spring.redis.database=0
    # Redis服务器地址
    spring.redis.host=106.14.72.179
    # Redis服务器连接端口
    spring.redis.port=6379
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # 连接池最大连接数(使用负值表示没有限制)
    spring.redis.jedis.pool.max-active=8
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.jedis.pool.max-wait=-1ms
    # 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=8
    # 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    # 连接超时时间(毫秒)
    spring.redis.timeout=5000
    

    3.配置 RedisConfig

    package com.example.demo.config;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    public class RedisConfig {
    
    	@Bean
    	@SuppressWarnings("all")
    	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    
    		RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
    
    		template.setConnectionFactory(factory);
    
    		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    
    		ObjectMapper om = new ObjectMapper();
    
    		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    
    		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    
    		jackson2JsonRedisSerializer.setObjectMapper(om);
    
    		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    
    		// key采用String的序列化方式
    
    		template.setKeySerializer(stringRedisSerializer);
    
    		// hash的key也采用String的序列化方式
    
    		template.setHashKeySerializer(stringRedisSerializer);
    
    		// value序列化方式采用jackson
    
    		template.setValueSerializer(jackson2JsonRedisSerializer);
    
    		// hash的value序列化方式采用jackson
    
    		template.setHashValueSerializer(jackson2JsonRedisSerializer);
    
    		template.afterPropertiesSet();
    
    		return template;
    
    	}
    }
    
    

    4.配置 RedisService

    package com.example.demo.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.util.CollectionUtils;
    
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    @Service
    public class RedisService {
    
    	@Autowired
    	private RedisTemplate<String, Object> redisTemplate;
    
    	// =============================common============================
    	/**
    	 * 指定缓存失效时间
    	 * @param key 键
    	 * @param time 时间(秒)
    	 * @return
    	 */
    	public boolean expire(String key, long time) {
    		try {
    			if (time > 0) {
    				redisTemplate.expire(key, time, TimeUnit.SECONDS);
    			}
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 根据key 获取过期时间
    	 * @param key 键 不能为null
    	 * @return 时间(秒) 返回0代表为永久有效
    	 */
    	public long getExpire(String key) {
    		return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    	}
    
    	/**
    	 * 判断key是否存在
    	 * @param key 键
    	 * @return true 存在 false不存在
    	 */
    	public boolean hasKey(String key) {
    		try {
    			return redisTemplate.hasKey(key);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 删除缓存
    	 * @param key 可以传一个值 或多个
    	 */
    	@SuppressWarnings("unchecked")
    	public void del(String... key) {
    		if (key != null && key.length > 0) {
    			if (key.length == 1) {
    				redisTemplate.delete(key[0]);
    			} else {
    				redisTemplate.delete(CollectionUtils.arrayToList(key));
    			}
    		}
    	}
    
    	/**
    	 * 删除缓存
    	 * @param keys 可以传一个值 或多个
    	 */
    	@SuppressWarnings("unchecked")
    	public void del(Collection keys) {
    		if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(keys)) {
    			redisTemplate.delete(keys);
    		}
    	}
    
    	// ============================String=============================
    	/**
    	 * 普通缓存获取
    	 * @param key 键
    	 * @return 值
    	 */
    	public Object get(String key) {
    		return key == null ? null : redisTemplate.opsForValue().get(key);
    	}
    
    	/**
    	 * 普通缓存放入
    	 * @param key 键
    	 * @param value 值
    	 * @return true成功 false失败
    	 */
    	public boolean set(String key, Object value) {
    		try {
    			redisTemplate.opsForValue().set(key, value);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 普通缓存放入并设置时间
    	 * @param key 键
    	 * @param value 值
    	 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
    	 * @return true成功 false 失败
    	 */
    	public boolean set(String key, Object value, long time) {
    		try {
    			if (time > 0) {
    				redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
    			} else {
    				set(key, value);
    			}
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 递增
    	 * @param key 键
    	 * @param delta 要增加几(大于0)
    	 * @return
    	 */
    	public long incr(String key, long delta) {
    		if (delta < 0) {
    			throw new RuntimeException("递增因子必须大于0");
    		}
    		return redisTemplate.opsForValue().increment(key, delta);
    	}
    
    	/**
    	 * 递减
    	 * @param key 键
    	 * @param delta 要减少几(小于0)
    	 * @return
    	 */
    	public long decr(String key, long delta) {
    		if (delta < 0) {
    			throw new RuntimeException("递减因子必须大于0");
    		}
    		return redisTemplate.opsForValue().increment(key, -delta);
    	}
    
    	// ================================Map=================================
    	/**
    	 * HashGet
    	 * @param key 键 不能为null
    	 * @param item 项 不能为null
    	 * @return 值
    	 */
    	public Object hget(String key, String item) {
    		return redisTemplate.opsForHash().get(key, item);
    	}
    
    	/**
    	 * 获取hashKey对应的所有键值
    	 * @param key 键
    	 * @return 对应的多个键值
    	 */
    	public Map<Object, Object> hmget(String key) {
    		return redisTemplate.opsForHash().entries(key);
    	}
    
    	/**
    	 * HashSet
    	 * @param key 键
    	 * @param map 对应多个键值
    	 * @return true 成功 false 失败
    	 */
    	public boolean hmset(String key, Map<String, Object> map) {
    		try {
    			redisTemplate.opsForHash().putAll(key, map);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * HashSet 并设置时间
    	 * @param key 键
    	 * @param map 对应多个键值
    	 * @param time 时间(秒)
    	 * @return true成功 false失败
    	 */
    	public boolean hmset(String key, Map<String, Object> map, long time) {
    		try {
    			redisTemplate.opsForHash().putAll(key, map);
    			if (time > 0) {
    				expire(key, time);
    			}
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 向一张hash表中放入数据,如果不存在将创建
    	 * @param key 键
    	 * @param item 项
    	 * @param value 值
    	 * @return true 成功 false失败
    	 */
    	public boolean hset(String key, String item, Object value) {
    		try {
    			redisTemplate.opsForHash().put(key, item, value);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 向一张hash表中放入数据,如果不存在将创建
    	 * @param key 键
    	 * @param item 项
    	 * @param value 值
    	 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
    	 * @return true 成功 false失败
    	 */
    	public boolean hset(String key, String item, Object value, long time) {
    		try {
    			redisTemplate.opsForHash().put(key, item, value);
    			if (time > 0) {
    				expire(key, time);
    			}
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 删除hash表中的值
    	 * @param key 键 不能为null
    	 * @param item 项 可以使多个 不能为null
    	 */
    	public void hdel(String key, Object... item) {
    		redisTemplate.opsForHash().delete(key, item);
    	}
    
    	/**
    	 * 删除hash表中的值
    	 * @param key 键 不能为null
    	 * @param items 项 可以使多个 不能为null
    	 */
    	public void hdel(String key, Collection items) {
    		redisTemplate.opsForHash().delete(key, items.toArray());
    	}
    
    	/**
    	 * 判断hash表中是否有该项的值
    	 * @param key 键 不能为null
    	 * @param item 项 不能为null
    	 * @return true 存在 false不存在
    	 */
    	public boolean hHasKey(String key, String item) {
    		return redisTemplate.opsForHash().hasKey(key, item);
    	}
    
    	/**
    	 * hash递增 如果不存在,就会创建一个 并把新增后的值返回
    	 * @param key 键
    	 * @param item 项
    	 * @param delta 要增加几(大于0)
    	 * @return
    	 */
    	public double hincr(String key, String item, double delta) {
    		if (delta < 0) {
    			throw new RuntimeException("递增因子必须大于0");
    		}
    		return redisTemplate.opsForHash().increment(key, item, delta);
    	}
    
    	/**
    	 * hash递减
    	 * @param key 键
    	 * @param item 项
    	 * @param delta 要减少记(小于0)
    	 * @return
    	 */
    	public double hdecr(String key, String item, double delta) {
    		if (delta < 0) {
    			throw new RuntimeException("递减因子必须大于0");
    		}
    		return redisTemplate.opsForHash().increment(key, item, -delta);
    	}
    
    	// ============================set=============================
    	/**
    	 * 根据key获取Set中的所有值
    	 * @param key 键
    	 * @return
    	 */
    	public Set<Object> sGet(String key) {
    		try {
    			return redisTemplate.opsForSet().members(key);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	/**
    	 * 根据value从一个set中查询,是否存在
    	 * @param key 键
    	 * @param value 值
    	 * @return true 存在 false不存在
    	 */
    	public boolean sHasKey(String key, Object value) {
    		try {
    			return redisTemplate.opsForSet().isMember(key, value);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 将数据放入set缓存
    	 * @param key 键
    	 * @param values 值 可以是多个
    	 * @return 成功个数
    	 */
    	public long sSet(String key, Object... values) {
    		try {
    			return redisTemplate.opsForSet().add(key, values);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    
    	/**
    	 * 将数据放入set缓存
    	 * @param key 键
    	 * @param values 值 可以是多个
    	 * @return 成功个数
    	 */
    	public long sSet(String key, Collection values) {
    		try {
    			return redisTemplate.opsForSet().add(key, values.toArray());
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    
    	/**
    	 * 将set数据放入缓存
    	 * @param key 键
    	 * @param time 时间(秒)
    	 * @param values 值 可以是多个
    	 * @return 成功个数
    	 */
    	public long sSetAndTime(String key, long time, Object... values) {
    		try {
    			Long count = redisTemplate.opsForSet().add(key, values);
    			if (time > 0)
    			expire(key, time);
    			return count;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    
    	/**
    	 * 获取set缓存的长度
    	 * @param key 键
    	 * @return
    	 */
    	public long sGetSetSize(String key) {
    		try {
    			return redisTemplate.opsForSet().size(key);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    
    	/**
    	 * 移除值为value的
    	 * @param key 键
    	 * @param values 值 可以是多个
    	 * @return 移除的个数
    	 */
    	public long setRemove(String key, Object... values) {
    		try {
    			Long count = redisTemplate.opsForSet().remove(key, values);
    			return count;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    
    	// ===============================list=================================
    	/**
    	 * 获取list缓存的内容
    	 * @param key 键
    	 * @param start 开始
    	 * @param end 结束 0 到 -1代表所有值
    	 * @return
    	 */
    	public List<Object> lGet(String key, long start, long end) {
    		try {
    			return redisTemplate.opsForList().range(key, start, end);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	/**
    	 * 获取list缓存的长度
    	 * @param key 键
    	 * @return
    	 */
    	public long lGetListSize(String key) {
    		try {
    			return redisTemplate.opsForList().size(key);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    
    	/**
    	 * 通过索引 获取list中的值
    	 * @param key 键
    	 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
    	 * @return
    	 */
    	public Object lGetIndex(String key, long index) {
    		try {
    			return redisTemplate.opsForList().index(key, index);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	/**
    	 * 将list放入缓存
    	 * @param key 键
    	 * @param value 值
    	 * @return
    	 */
    	public boolean lSet(String key, Object value) {
    		try {
    			redisTemplate.opsForList().rightPush(key, value);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 将list放入缓存
    	 * @param key 键
    	 * @param value 值
    	 * @param time 时间(秒)
    	 * @return
    	 */
    	public boolean lSet(String key, Object value, long time) {
    		try {
    			redisTemplate.opsForList().rightPush(key, value);
    			if (time > 0)
    			expire(key, time);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 将list放入缓存
    	 * @param key 键
    	 * @param value 值
    	 * @return
    	 */
    	public boolean lSet(String key, List<Object> value) {
    		try {
    			redisTemplate.opsForList().rightPushAll(key, value);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    	/**
    	 * 将list放入缓存
    	 *
    	 * @param key 键
    	 * @param value 值
    	 * @param time 时间(秒)
    	 * @return
    	 */
    	public boolean lSet(String key, List<Object> value, long time) {
    		try {
    			redisTemplate.opsForList().rightPushAll(key, value);
    			if (time > 0)
    			expire(key, time);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    		/**
    		 * 根据索引修改list中的某条数据
    		 * @param key 键
    		 * @param index 索引
    		 * @param value 值
    		 * @return
    		 */
    	public boolean lUpdateIndex(String key, long index, Object value) {
    		try {
    			redisTemplate.opsForList().set(key, index, value);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return false;
    		}
    	}
    
    		/**
    		 * 移除N个值为value
    		 * @param key 键
    		 * @param count 移除多少个
    		 * @param value 值
    		 * @return 移除的个数
    		 */
    	public long lRemove(String key, long count, Object value) {
    		try {
    			Long remove = redisTemplate.opsForList().remove(key, count, value);
    			return remove;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    }
    
    

    5.至此,Redis已经配置好了,接下来是具体调用测试

    package com.example.demo.controller;
    
    import com.example.demo.converter.UserConverter;
    import com.example.demo.domain.Blog;
    import com.example.demo.service.BlogService;
    import com.example.demo.service.RedisService;
    import com.example.demo.support.ApiResponse;
    import com.example.demo.support.UserHolder;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.ModelAndView;
    
    import java.util.Map;
    
    @Controller
    @RequestMapping("/blogs")
    public class BlogController {
    
    	@Autowired
    	private BlogService blogService;
    	@Autowired
    	private RedisService redisService;
    
    	@RequestMapping("/{id}")
    	public ModelAndView blog(@PathVariable("id") Long blogId) {
    		ModelAndView view = new ModelAndView("blog-detail");
    		//查看博客信息,先根据id从Redis中找
    		Blog blog = (Blog) redisService.get("blog_" + blogId);
    		//如果Redis中没有,查询Mysql
    		if (blog == null) {
    			blog = blogService.getBlogById(blogId);
    			//将博客信息放入Redis,并且设置失效时间
    			redisService.set("blog_" + blogId, blog,60);
    		}
    		Map modelMap = view.getModelMap();
    		modelMap.put("userVO", UserConverter.toUserVO(UserHolder.get()));
    		modelMap.put("blogVO", blog);
    		modelMap.put("isArchives",true);
    		return view;
    	}
    	
    	@RequestMapping(value = "/save",method = RequestMethod.POST)
    	@ResponseBody
    	public ApiResponse edit(Blog blogVO) {
    		int num =  blogService.save(blogVO);
    		if (num == 0) {
    			return ApiResponse.fail().error("保存失败");
    		}
    		//新增、修改博客后,将最新的博客信息放入Redis,并且设置失效时间
    		redisService.set("blog_" + blogVO.getBlogId(), blogVO,60);
    		return ApiResponse.success().and("msg", "保存成功").and("blogId",blogVO.getBlogId());
    	}
    }
    
    

    6.完成

    SpringBoot项目使用Redis做缓存

    1.项目pom文件引入Cache和Redis依赖

    <!-- kaptcha -->  
    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    2.配置application.properties

    ## Redis部分
    # Redis数据库索引(默认为0)
    spring.redis.database=0
    # Redis服务器地址
    spring.redis.host=106.14.72.179
    # Redis服务器连接端口
    spring.redis.port=6379
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # 连接池最大连接数(使用负值表示没有限制)
    spring.redis.jedis.pool.max-active=8
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.jedis.pool.max-wait=-1ms
    # 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=8
    # 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    # 连接超时时间(毫秒)
    spring.redis.timeout=5000
    
    ## Cache部分
    #缓存的名称集合,多个采用逗号分割
    spring.cache.cache-names=
    #缓存的类型,官方提供了很多,这里我们填写redis
    spring.cache.type=redis
    #是否缓存null数据,默认是false
    spring.cache.redis.cache-null-values=false
    #redis中缓存超时的时间,默认60000ms
    spring.cache.redis.time-to-live=60000
    #缓存数据key是否使用前缀,默认是true
    spring.cache.redis.use-key-prefix=true
    #缓存数据key的前缀,在上面的配置为true时有效,
    spring.cache.redis.key-prefix=
    

    3.配置Configuration

    package com.example.demo.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.CacheManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import java.time.Duration;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;
    
    @Configuration
    public class CacheConfig  {
    
    	@Bean
    	CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    		RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
    
    		//common信息缓存配置
    		RedisCacheConfiguration userCacheConfiguration = defaultCacheConfig
    				// 设置 key为string序列化
                    .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
    				// 设置value为json序列化
    				.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())).disableCachingNullValues();
    		Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
    		//entryTtl设置缓存失效时间,单位是秒
    		redisCacheConfigurationMap.put("common", userCacheConfiguration.entryTtl(Duration.ofSeconds(30)));
    
    
    		//设置CacheManager的值序列化方式为JdkSerializationRedisSerializer,但其实RedisCacheConfiguration默认就是使用StringRedisSerializer序列化key,JdkSerializationRedisSerializer序列化value,所以以下注释代码为默认实现
    		//ClassLoader loader = this.getClass().getClassLoader();
    		//JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(loader);
    		//RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jdkSerializer);
    		//RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
    
    		Set<String> cacheNames = new HashSet<>();
    		cacheNames.add("common");
    		//初始化RedisCacheManager
    		RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory).cacheDefaults(defaultCacheConfig).initialCacheNames(cacheNames).withInitialCacheConfigurations(redisCacheConfigurationMap).build();
    		return cacheManager;
    	}
    }
    
    

    4.启动类Application或App加@EnableCaching注解

    package com.example.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    @SpringBootApplication
    @EnableCaching
    public class DemoApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    	}
    
    }
    

    5.缓存注解的使用

    • Cacheable:调用方法时先从缓存中查询有没有对应key的数据,如果有直接从缓存获取返回,如果没有则执行方法,将返回值存入缓存中。
    • CacheEvict:调用方法后从缓存中删除对应key的数据
    • Caching:当一个方法需要查询多个缓存或者删除多个缓存时使用
    package com.example.demo.service;
    
    import com.example.demo.domain.Blog;
    import com.example.demo.domain.BlogExample;
    import com.example.demo.enumdata.EnumBlogType;
    import com.example.demo.mapper.BlogMapper;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.cache.annotation.Caching;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Service
    public class BlogService {
    
    	@Resource
    	private BlogMapper blogMapper;
    
    	//unless 参数就是不执行Cacheable的条件
    	@Cacheable(value = "common", key = "'blog_'+#blogId", unless = "#blogId == null")
    	public Blog getBlogById (Long blogId) {
    		return blogMapper.selectByPrimaryKey(blogId);
    	}
    
    	//condition 参数就是执行Cacheable的条件
    	@Cacheable(value = "common", key = "'blog_by_page'",condition = "#page == null")
    	public List<Blog> getBlogByPage (Integer page, Integer size) {
    		int start = 0;
    		if (size == null)
    			size = 10;
    		if (page != null) {
    			page = page <= 0 ? 1 : page;
    			start = (page - 1) * size;
    		}
    		BlogExample example = new BlogExample();
    		example.setOrderByClause("blog_id desc limit "+ start + ","+ size);
    		return blogMapper.selectByExampleWithBLOBs(example);
    	}
    
    	@Cacheable(value = "common", key = "'blog_all'")
    	public List<Blog> getBlogs () {
    		BlogExample example = new BlogExample();
    		example.setOrderByClause("blog_id desc");
    		return blogMapper.selectByExampleWithBLOBs(example);
    	}
    
    	//执行下面方法需要删除三个缓存的数据,所以使用Caching
    	@Transactional
    	@Caching(evict={@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
    	public int save (Blog blog) {
    		if (blog == null) return 0;
    		if (blog.getBlogId() == null) {
    			return insert(blog);
    		}
    		return update(blog);
    	}
    
    	public int insert (Blog blog) {
    		if (StringUtils.isBlank(blog.getAuthor()))blog.setAuthor("Cocoivan");
    		if (blog.getBlogType() == null)blog.setBlogType(EnumBlogType.MISCELLANEOUS.getValue());
    		return blogMapper.insertSelective(blog);
    	}
    
    	public int update (Blog blog) {
    		return blogMapper.updateByPrimaryKeySelective(blog);
    	}
    }
    
    

    6.注意

    Spring @Cacheable、@CacheEvict、@Caching是基于Spring AOP代理类,内部方法调用时,注解是失效的。

    举例子,Controller接收请求调用BlogService.save方法
    缓存相关注解不生效
    	@Transactional
    	public int save (Blog blog) {
    		if (blog == null) return 0;
    		if (blog.getBlogId() == null) {
    			return insert(blog);
    		}
    		return update(blog);
    	}
    
    	@Caching(evict={@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
    	public int insert (Blog blog) {
    		if (StringUtils.isBlank(blog.getAuthor()))blog.setAuthor("Cocoivan");
    		if (blog.getBlogType() == null)blog.setBlogType(EnumBlogType.MISCELLANEOUS.getValue());
    		return blogMapper.insertSelective(blog);
    	}
    
    	@Caching(evict={@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
    	public int update (Blog blog) {
    		return blogMapper.updateByPrimaryKeySelective(blog);
    	}
    
    缓存相关注解生效
    	@Transactional
    	@Caching(evict={@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
    			, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
    	public int save (Blog blog) {
    		if (blog == null) return 0;
    		if (blog.getBlogId() == null) {
    			return insert(blog);
    		}
    		return update(blog);
    	}
    
    	public int insert (Blog blog) {
    		if (StringUtils.isBlank(blog.getAuthor()))blog.setAuthor("Cocoivan");
    		if (blog.getBlogType() == null)blog.setBlogType(EnumBlogType.MISCELLANEOUS.getValue());
    		return blogMapper.insertSelective(blog);
    	}
    
    	public int update (Blog blog) {
    		return blogMapper.updateByPrimaryKeySelective(blog);
    	}
    

    7.完成

    展开全文
  • springboot整合redis做缓存

    万次阅读 多人点赞 2018-09-13 13:39:33
    之前的项目中,用到过redis,主要是使用redis做缓存redis在web开发中使用的场景很多,其中缓存是其中一个很重要的使用场景,之所以用作缓存,得益于redis的读写数据,尤其是在读取数据的时候是直接走内存的,这样...

    之前的项目中,用到过redis,主要是使用redis做缓存,redis在web开发中使用的场景很多,其中缓存是其中一个很重要的使用场景,之所以用作缓存,得益于redis的读写数据,尤其是在读取数据的时候是直接走内存的,这样在高并发访问数据的时候,和查询数据库相比,redis读取数据的高效性、快速性的优势可见一斑,据说新浪单是每天的所有内容的统计的总的访问数量可以达到上百亿次,这种场景下,如果没有redis做数据缓存,根本无法支撑这么大的数据访问量,redis使用的时候可以单独利用客户端引入jar包操作即可,实际项目中都是和框架进行整合的比较多,此处演示利用springboot整合redis做缓存的简单过程。

    1、搭建redis服务器,为简化搭建过程,这里是在windows下使用redis3.2进行模拟,redis的下载可到github上,

    这里写图片描述

    下载压缩包,解压到本地的目录,解压完毕,直接在目录下启动服务端和客户端即可,

    展开全文
  • 为什么要用Redis做缓存

    千次阅读 2019-09-04 21:38:41
    Redis的简介 简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向。另外,redis 也经常...为什么要Redis做缓存? ...

    Redis的简介

    简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向。另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务场景。除此之外,redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。 

    为什么要Redis做缓存?

    主要从“高性能”和“高并发”这两点来看待这个问题。

    高性能:

    假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在数缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!

    高并发:

    直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

    为什么要用 redis 而不用 map/guava 做缓存?

     缓存分为本地缓存和分布式缓存。以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 JVM的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。

    使用 redis 或 memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。缺点是需要保持 redis 或 memcached服务的高可用,整个程序架构上较为复杂。

    展开全文
  • SpringBoot整合Redis做缓存,实战分享

    千次阅读 2020-07-07 08:40:00
    我们都知道,把首页数据放到Redis里,能够加快首页数据的访问速度。但是我们要如何准确又快速的将 Redis 整合到自己的 SpringBoot2.x 项目中呢?今天阿粉就带大家爬一爬其...


    我们都知道,把首页数据放到Redis里,能够加快首页数据的访问速度。但是我们要如何准确又快速的将 Redis 整合到自己的 SpringBoot2.x 项目中呢?今天阿粉就带大家爬一爬其中的门门道道。

    Redis 介绍

    Redis 使用了浪费流量的文本协议,但因为它数据存储在内存中的,相对而言,依然可以取得极高的访问性能。并且 Redis 是线程安全的。

    RESP 就是 Redis 序列化协议的简称。它是一种直观的文本协议,优势在于实现异常简单,解析性能极好。

    Redis 协议里面虽然有大量冗余的回车换行符,但是这不影响它成为技术领域非常受欢迎的一个文本协议。在技术领域,性能并不总是一切,还有简单性、易理解性和易实现性,这些都需要进行适当权衡。

    Redis 基础数据结构

    1、字符串:(缓存)

    • key:value

    value 可以是对象转换成的 JSON 字符串,也可以是对象序列化后的二进制字符串

    2、列表:(异步队列) 类似linkedlist

    • 右边进左边出:队列

    • 右边进右边出:栈

    3、字典(哈希) 类似hashmap:数组+链表

    不过rehash是渐进式hash策略

    4、集合:(去重)

    • 无序 set:类似hashset

    • 有序 zset:类似SortedSet和HashMap的结合体,内部实现是跳跃列表

    Lettuce

    随着 Spring Boot2.x 的到来,支持的组件越来越丰富,也越来越成熟,其中对 Redis 的支持不仅仅是丰富了它的API,更是替换掉底层 Jedis 的依赖,取而代之换成了 Lettuce。

    虽然 Lettuce 和 Jedis 的都是连接 Redis Server 的客户端程序,但是 Jedis 在实现上是直连 redis server,多线程环境下非线程安全,除非使用连接池,为每个Jedis实例增加物理连接。而 Lettuce 基于 Netty 的连接实例(StatefulRedisConnection),可以在多个线程间并发访问,且线程安全,满足多线程环境下的并发访问,同时它是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

    Lettuce是可扩展的Redis客户端,用于构建无阻塞的Reactive应用程序.

    Luttuce官网:https://lettuce.io/

    谷歌翻译后的页面是:

    原来这玩意儿叫生菜,你别说,看着图标还真有点像。


    实操

    项目中使用的 SpringBoot2.x 实现,如果之前是 SpringBoot1.x 则需要注意,底层已经由 Jedis 升级成了 Lettuce 。

    3.1、引入依赖

    除去 SpringBoot 项目需要的 jar 包外,另外还需要引入 redis 相关的依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    

    3.2、application.yml 配置文件

    此处用到的 application.yml 文件,配置如下:

    spring:
      redis:
        # Redis默认情况下有16个分片,这里配置具体使用的分片。默认是索引为0的分片
        database: 1
        # Redis服务器地址
        host: 127.0.0.1
        # Redis服务器连接端口
        port: 6379
        # Redis服务器连接密码(默认为空)
        password: mmzsblog
        # 连接超时时间(毫秒)
        timeout: 2000s
    
        # 配置文件中添加 lettuce.pool 相关配置,则会使用到lettuce连接池
        lettuce:
          pool:
            # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
            max-wait: 60s
            # 连接池中的最大空闲连接 默认 8
            max-idle: 10
            # 连接池中的最小空闲连接 默认 0
            min-idle: 10
            # 连接池最大连接数(使用负值表示没有限制) 默认 8
            max-activ: 8
    

    如果项目是由 SpringBoot1.x 升级到 SpringBoot2.x 的,要沿用 jedis 连接池配置时会用到配置 jedis 相关的属性:

        # 配置文件中添加 jedis.pool 相关配置,则会使用到 jedis 连接池
        jedis:
          pool:
            max-active: 10
            max-idle: 8
            min-idle: 0
            max-wait: 60s
    

    并且引用的 jar 包也需要调整:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <exclusions>
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    

    另外,这里再贴一下 Spring Boot 关于 RedisProperties 的所有配置项

    # REDIS RedisProperties
    spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster.
    spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from.
    spring.redis.database=0 # Database index used by the connection factory.
    spring.redis.url= # Connection URL. Overrides host, port, and password. User is ignored. Example: redis://user:password@example.com:6379
    spring.redis.host=localhost # Redis server host.
    spring.redis.jedis.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
    spring.redis.jedis.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
    spring.redis.jedis.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
    spring.redis.jedis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
    spring.redis.lettuce.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
    spring.redis.lettuce.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
    spring.redis.lettuce.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
    spring.redis.lettuce.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
    spring.redis.lettuce.shutdown-timeout=100ms # Shutdown timeout.
    spring.redis.password= # Login password of the redis server.
    spring.redis.port=6379 # Redis server port.
    spring.redis.sentinel.master= # Name of the Redis server.
    spring.redis.sentinel.nodes= # Comma-separated list of "host:port" pairs.
    spring.redis.ssl=false # Whether to enable SSL support.
    spring.redis.timeout= # Connection timeout.
    

    3.3、自定义一个 RedisTemplate

    这个看你自己,不自定义也不影响使用,只是说可能不那么顺手,所以阿粉习惯自定义一个。因为 Spring BootRedisAutoConfiguration 中默认配置了 RedisTemplate<Object, Object>StringRedisTemplate两个模板类,然而RedisTemplate<Object, Object>并未指定keyvalue的序列化器。

    @Configuration
    public class RestTemplateConfig {
        @Bean
        public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Serializable> template = new RedisTemplate<>();
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    }
    

    3.4、Person 实体类

    声明一个 Person 实体类:

    /**
     * @author :created by mmzsblog
     * @date :created at 2020/06/23 16:41
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Person implements Serializable {
    
        private static final long serialVersionUID = -8183942491930372236L;
        private Long userId;
        private String username;
        private String password;
    }
    

    3.5、测试

    通过编写一个 UserController 来进行测试:

    @RestController
    public class UserController {
        @Resource
        private RedisTemplate redisTemplate;
    
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
        @GetMapping("/set")
        public String set() {
            stringRedisTemplate.opsForValue().set("one", "1");
            
            // redisTemplate 保存的是字节序列,因为 RestTemplateConfig 自定义的时候指定了 key 和 value 的序列化器。
            redisTemplate.opsForValue().set("two", "2");
            redisTemplate.opsForValue().set("person", new Person(1L, "luffy", "123456789"));
    
            // 测试线程安全
            ExecutorService executorService = Executors.newFixedThreadPool(1000);
            IntStream.range(0, 1000).forEach(i -> {
                executorService.execute(() -> stringRedisTemplate.opsForValue().increment("num", 1));
            });
            return "Ok!";
        }
    
        @GetMapping("/get")
        public String get() {
            String one = stringRedisTemplate.opsForValue().get("one");
            if ("1".equals(one)) {
                System.out.println("key: one" + " || value: " + one);
            }
    
            Object two = redisTemplate.opsForValue().get("two");
            if ("2".equals(two.toString())) {
                System.out.println("key: two" + " || value: " + two);
            }
    
            Person user = (Person) redisTemplate.opsForValue().get("person");
            if ("luffy".equals(user.getUsername())) {
                System.out.println("key: person" + " || value: " + user);
            }
            return "Ok!";
        }
    }
    

    用RedisDesktopManager工具查看,数据如下:

    StringRedisTemplate 设置的键值是String类型的:

    RedisTemplate 设置的键值是二进制的字节流形式存储的,从截图中的 [Binary] 标识符也能看出:

    自定义的 RedisTemplateStringRedisTemplate 并不会有什么冲突,想用 String 存储还是二进制的字节流形式存储完全取决于你自己。

    参考

    • https://lettuce.io/

    • Spring Boot官方文档 91.4

    • 《Redis深度历险:核心原理和应用实践》

    • http://blog.battcn.com/2018/05/11/springboot/v2-nosql-redis/

    • https://www.jianshu.com/p/f7d11e7109b7


    推荐阅读
    你亲手写的代码,正在出卖你

    深夜,聊聊设计模式
    深夜,分享一个Git小技巧

    编程·思维·职场
    欢迎扫码关注
    
    
    展开全文
  • 本文介绍Spring boot 如何使用redis缓存,如何对redis缓存进行定制化配置(如key的有效期)以及spring boot 如何初始化redis缓存。使用具体的代码介绍了@Cacheable,@CacheEvict,@CachePut,@CacheConfig等注解...
  • redis 做缓存的两种场景

    千次阅读 2019-04-29 10:32:28
    redis 做缓存的两种场景 1.当多次访问同一类数据的时候,可以将此种类型的数据从pg或MySQL等关系型数据库中取出来,放入Redis里面,加快响应的速度 2.当从海量数据中查询一个数据时,比如从10万条数据中查询一条...
  • ...1.Redis做缓存的话,相当于是一个第三方缓存,所以项目重启之后缓存数据还是存在的 2.SpringCache作缓存的话是建立在JVM上的,所以项目启动之后缓存是自动消失的。 业务:在邮件验证码、短...
  • springboot+Redis 缓存实现,内含idea项目、sql文件等,如若使用需要更改数据库目录,postman测试即可
  • 虽然EhCache已经能够适用很多应用场景,但是由于EhCache是进程内的缓存...就不能再使用EhCache来解决了,这个时候使用集中式缓存是个不错的选择,因此本文将介绍如何在Spring Boot的缓存支持中使用Redis进行数据缓存
  • redis做缓存的实现方式

    千次阅读 2019-05-29 11:39:10
    首先Java中使用Redis有2种方式:一种是使用标准Jedis来操作Redis实例,另一种是使用spring-data-redis来操作Redis实例。 如果使用jedis来操作redis,可以通过java代码实现setNX指令来保证操作的原子性。 jedis.set...
  • 1、 Redis简介 redis是Nosql数据库中使用较为广泛的非关系型内存数据库,redis内部是一个key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序...
  • 基于redis做缓存分页

    千次阅读 2018-02-02 11:20:00
    第二:基于redis的数据结构做缓存分页,这里又分2种 ①:基于redis的list数据结构,直接通过list的数据结构,用range方法可以进行分页,在数据量大的时候,性能也很可观,但是当存在接口高并发访问时,这个list...
  • 1、存redis 使用setex命令可以同时设置数据和保存时间 $data = [ 'name'=>zhangsan, 'age' => 28, 'sex' => 1 ]; Redis::setex($cacheKey, 300, serialize($data)); 2、取redis if ...
  • 为什么要使用缓存?说到底是为了提高系统的运行速度。将用户频繁访问的内容存放在离用户最近,访问速度最快的地方,提高用户的响应速度。下面我们来一起深入学习一下吧
  • WEB项目,使用redis做缓存小案例

    千次阅读 2018-03-02 15:02:06
    1.需求场景展示实时数据2....实现步骤(1)链接redis public static Jedis getJedisConnection() {  String redishost = "127.0.0.1";  int redisport = 6379;// redis的端口  int r...
  • 在项目中redis做缓存的一些思路

    万次阅读 多人点赞 2016-06-26 00:36:31
    2:对于一些不分页,不需要实时(需要多表查询)的列表,我们可以将列表结果缓存redis中,设定一定缓存时间作为该数据的存活时间。用获取该列表的方法名作为key,列表结果为value;这种情况只试用于不经常更新且不...
  • 本篇文章主要介绍了详解Spring Boot使用redis实现数据缓存,小编觉得挺不错的,现在分享给大家,也给大家个参考。一起跟随小编过来看看吧
  • SpringBoot 2.x 整合 redis 做缓存

    万次阅读 多人点赞 2018-06-17 16:18:15
    SpringBoot 2.x 整合 redis 做缓存 SpringBoot 2.0在今年3月份正式发布,公司新起的项目中就使用了SpringBoot 2.0,相比1.0还是有比较多的改动。SpringBoot 自2.0起不再支持jdk1.8以下的版本,jdk1.8中引入的...
  • 如何在项目中直接用redis做缓存

    千次阅读 2017-11-07 13:03:09
    前几天,在JFinal项目的时候,把以前用ssm框架写的小程序登录判断session是否过期的登录demo整合到JFinal这个项目中了,因为没有用 stringRedisTemplate,所以需要用到redis插件, 但是用redis插件后, 还是报错...
  • redis入门: 1、Redis服务器搭建 2、向业务逻辑中添加缓存。 3、使用redis做缓存 4、缓存同步
  • 本文主要简单的使用Java代码进行redis缓存,即在查询的时候先在service层从redis缓存中获取数据。如果大家对在ssm项目中使用redis缓存查询数据的相关知识感兴趣的朋友跟随脚本之家小编一起看看吧
  • 今天小编就为大家分享一篇关于SpringBoot AOP控制Redis自动缓存和更新的示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • 关于redis作为缓存时出现的击穿,穿透,雪崩问题1.击穿2.穿透3.缓存雪崩 redis有两种使用方式一是作为数据库使用,二是作为缓存使用。 将redis作为缓存,当你新增数据时,让它自动地回收旧数据是件很方便的事情。这...
  • redis做缓存手动更新

    千次阅读 2018-08-12 08:41:38
    server11:redis缓存服务器 server12:mysql服务器:client serever13:ngnx+php-fpm,gearmand server,worker server11: 首先安装redis服务器 server13: rpm包安装nginx+php-fpm vim /etc/php.ini 946 date....
  • 缓存数据库redis

    2016-05-02 16:37:58
    redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统。和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的value类型相对更多。技术博客http://blog.csdn.net/zcjfzcjf
  • 首先 pip install django-redis依赖包在django的settings下做缓存配置,这里设置使用redis数据库做缓存#===================================系统缓存设置=================================================== ...
  • 本篇文章主要介绍了Java自定义注解实现Redis自动缓存的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
  • SpringBoot使用redis做缓存机制

    千次阅读 2018-07-04 15:06:02
    SpringBoot 2.0.3 版本、redis3.2版本 1. 加入jar包 &amp;amp;lt;dependency&amp;amp;gt; &amp;amp;lt;groupId&amp;amp;gt;org.springframework.boot&amp;amp;lt;/groupId&amp;amp;gt;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 277,289
精华内容 110,915
关键字:

redis做缓存

redis 订阅