赞
踩
Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为
STRING(字符串)、LIST(列表)、SET(集合)、HASH(散列)和ZSET(有序集合)。
有一部分Redis命令对于这5种结构都是通用的,如DEL、TYPE、RENAME等;但也有一部分Redis命令只能对特定的一种或者两种结构使用;
名称 | 类型 | 数据存储选项 | 查询类型 | 附加功能 |
---|---|---|---|---|
Redis | 使用内存存储(in-memory)的非关系数据库 | 字符串、列表、集合、散列表、有序集合 | 每种数据类型都有自己的专属命令,另外还有批量操作(bulk operation)和不完全(partial)的事务支持 | 发布与订阅,主从复制(master/slave replication),持久化,脚本(存储过程,stored procedure) |
memcached | 使用内存存储的键值缓存 | 键值之间的映射 | 创建命令、读取命令、更新命令、删除命令以及其他几个命令 | 为提升性能而设的多线程服务器 |
MySQL | 关系数据库 | 每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图(view);支持空间(spatial)和第三方扩展 | SELECT、 INSERT、 UPDATE、 DELETE、函数、存储过程 | 支持ACID性质(需要使用InnoDB),主从复制和主主复制 (master/master replication) |
PostgreSQL | 关系数据库 | 每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图;支持空间和第三方扩展;支持可定制类型 | SELECT、 INSERT、 UPDATE、 DELETE、内置函数、自定义的存储过程 | 支持ACID性质,主从复制,由第三方支持的多主复制(multi-master replication) |
MongoDB | 使用硬盘存储(on-disk)的非关系文档存储 | 每个数据库可以包含多个表,每个表可以包含多个无schema(schema-less)的BSON文档 | 创建命令、读取命令、更新命令、删除命令、条件查询命令等 | 支持map-reduce操作,主从复制,分片,空间索引(spatial index) |
==表格样式不是我能决定的,凑合看吧==
结构类型 | 结构存储的值 | 结构的读写能力 |
---|---|---|
STRING | 可以是字符串、整数或者浮点数 | 对整个字符串或者字符串的其中一部分执行操作;对整数和浮点数执行自增(increment)或者自减(decrement)操作 |
LIST | 一个链表,链表上的每个节点都包含了一个字符串 | 从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值查找或者移除元素 |
SET | 包含字符串的无序收集器(unordered collection),并且被包含的每个字符串都是独一无二、各不相同的 | 添加、获取、移除单个元素;检查一个元素是否存在于集合中;计算交集、并集、差集;从集合里面随机获取元素 |
HASH | 包含键值对的无序散列表 | 添加、获取、移除单个键值对;获取所有键值对 |
ZSET(有序集合) | 字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定 | 添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素 |
源码简单 ,约23000行C语言源代码。
flushdb:清空当前数据库;
select [index]:选择索引数据库,index为索引值名,如:select 1;
del [key]:删除一条指定key的值;
keys *:查看数据库内所有的key;
flushall:清空所有数据库;
quit:退出客户端连接。
==友情提示:部分命令慎用,线上一定不能用==
redis-server --service-install redis.windows.conf --loglevel verbose
卸载服务:
redis-server --service-uninstall
启动Redis:
redis-server.exe
指定配置文件启动,适用于多个redis数据库的时候
redis-server.exe redis.windows.conf停止Redis:
redis-server --service-stop安装成功:
启动redis:
redis支持的语言,可在官网查看!重点看下redis的java客户端jedis:
github地址:https://github.com/xetorthio/jedis
spring boot整合redis有两种方式:
其一:使用外部配置,通过jedis技术框架实现;
其二:通过spring boot提供的数据访问框架Spring Data Redis实现,它是基于Jedis的。
第一种方式,可以参考SSM框架整合jedis进行操作配置;重点是第二种实现方式!
通过spring boot中的redis自动配置类,关于redis自动配置类RedisAutoConfiguration.java
- //排除redis自动配置注解
- @EnableAutoConfiguration(exclude = RedisAutoConfiguration.class)
查看其源码:
spring boot在Spring Data Redis提供了两个模板:
RedisTemplate会使用JdkSerializationRedisSerializer处理数据,这意味着key和value都会通过Java进行序列化。
StringRedisTemplate默认会使用StringRedisSerializer处理数据。
要是操作字符串的话,用StringRedisTemplate就可以满足。但要是想要存储一个对象Object,我们就需要使用RedisTemplate,并对key采用String序列化方式,对value采用json序列化方式,这时候就需要对redisTemplate自定义配置,项目源码片段:
- /**
- * 实例化 RedisTemplate 对象
- *
- * @return RedisTemplate
- */
- @Bean
- public RedisTemplate<String, Object> functionDomainRedisTemplate() {
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setConnectionFactory(redisConnectionFactory);
- initDomainRedisTemplate(redisTemplate);
- redisTemplate.afterPropertiesSet();
- return redisTemplate;
- }
-
- /**
- * 设置数据存入 redis 的序列化方式
- * </br>redisTemplate 序列化默认使用的jdkSerializeable, 存储二进制字节码, 导致key会出现乱码,所以自定义
- * 序列化类
- *
- * @param redisTemplate
- * @param factory
- */
- private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
- // 使用Jackson2JsonRedisSerialize 替换默认序列化
- 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);
- string结构的数据,设置value的序列化规则和 key的序列化规则
- //StringRedisSerializer解决key中乱码问题。//Long类型不可以会出现异常信息;
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- //value乱码问题:Jackson2JsonRedisSerializer
- redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
-
- //设置Hash结构的key和value的序列化方式
- //redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
- //redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
- }
方 法 | 子API接口 | 描 述 |
---|---|---|
opsForValue() | ValueOperations<K, V> | 操作具有简单值的条目 |
opsForList() | ListOperations<K, V> | 操作具有list值的条目 |
opsForSet() | SetOperations<K, V> | 操作具有set值的条目 |
opsForZSet() | ZSetOperations<K, V> | 操作具有ZSet值(排序的set)的条目 |
opsForHash() | HashOperations<K, HK, HV> | 操作具有hash值的条目 |
boundValueOps(K) | BoundValueOperations<K,V> | 以绑定指定key的方式,操作具有简单值的条目 |
boundListOps(K) | BoundListOperations<K,V> | 以绑定指定key的方式,操作具有list值的条目 |
boundSetOps(K) | BoundSetOperations<K,V> | 以绑定指定key的方式,操作具有set值的条目 |
boundZSet(K) | BoundZSetOperations<K,V> | 以绑定指定key的方式,操作具有ZSet值(排序的set)的条目 |
boundHashOps(K) | BoundHashOperations<K,V> | 以绑定指定key的方式,操作具有hash值的条目 |
spring boot集成redis进行数据缓存功能;有两种实现:
1,通过在代码中调用redis API实现数据的CRUD;
【参考RedisUtils工具类,该工具类支持redis的其他业务场景】
2,通过在方法上添加缓存注解实现;
【重点介绍,只支持redis作为缓存管理时使用】
Spring 提供了很多缓存管理器,例如:
在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),默认情况下Spring Boot根据下面的顺序自动检测缓存提供者:
因为之前已经配置了RedisTemplate了,Spring Boot就无法自动给RedisCacheManager设置RedisTemplate了,所以要自己配置CacheManager。
1, 修改RedisConfig配置类,添加@EnableCaching注解,并继承CachingConfigurerSupport,重写CacheManager 方法:
- /**
- * 实例化 CacheManager 对象,指定使用RedisCacheManager作缓存管理
- *
- * @return CacheManager
- */
- @Bean
- public CacheManager cacheManager(RedisTemplate redisTemplate) {
- RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
- // 设置缓存过期时间(单位:秒),60秒
- rcm.setDefaultExpiration(120);
- return rcm;
- }
Spring提供了如下注解来声明缓存规则:
注 解 | 描 述 |
---|---|
@Cacheable | 表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则的话,这个方法就会被调用,返回值会放到缓存之中 |
@cacheput | 表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会 检查缓存,方法始终都会被调用 |
@cacheevict | 表明Spring应该在缓存中清除一个或多个条目 |
@caching | 这是一个分组的注解,能够同时应用多个其他的缓存注解 |
@cacheconfig | 可以在类层级配置一些共用的缓存配置 |
@Cacheable和@cacheput有一些共有的属性:
属 性 | 类 型 | 描 述 |
---|---|---|
value | String[] | 要使用的缓存名称 |
condition | String | SpEL表达式,如果得到的值是false的话,不会将缓存应用到方法调用上 |
key | String | SpEL表达式,用来计算自定义的缓存key |
unless | String | SpEL表达式,如果得到的值是true的话,返回值不会放到缓存之中 |
2, 通过注解@Cacheable,对数据进行缓存处理:
代码片段:
- /**
- * 通过缓存注解,添加数据到redis中
- * </br>实现数据缓存!
- * @param cat 对象
- */
- @Cacheable
- @RequestMapping(value = "/getCat/{catId}", method = RequestMethod.GET)
- @ResponseBody
- public Cat add(@PathVariable("catId") int catId){
- return this.catService.getCat(catId);
- }
注意:Cat对象必须实现implements Serializable接口!
启动访问:http://127.0.0.1:8066/redis/getCat/1
- java.lang.IllegalStateException: No cache could be resolved for 'Builder[public com.wyait.redis.pojo.Cat com.wyait.redis.controller.RedisCacheController.add(int)] caches=[] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@5e67a11d'. At least one cache should be provided per cache operation.
- at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:244) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
这个错误,是由于@Cacheable注解没有指定缓存名称导致的。加上value值,再试:
@Cacheable(value = "catCache")
测试访问成功!多次访问,走redis缓存。
3, redis缓存key生成策略
键的生成策略有两种,一种是默认策略,一种是自定义策略。
----------------------------默认策略:
- If no params are given, return SimpleKey.EMPTY.
- If only one param is given, return that instance.
- If more the one param is given, return a SimpleKey containing all parameters.
默认的key是通过KeyGenerator生成的,其默认策略如下:
1.如果方法没有参数,则使用0作为key;
2.如果只有一个参数的话则使用该参数作为key;
3.如果参数多于一个则使用所有参数的hashcode作为key;
之前在redisTemplate里设置了template.setKeySerializer(new StringRedisSerializer()),需要key是string类型。也可以使用SpEL表达式生成Key,
(SpEL表达式:http://itmyhome.com/spring/expressions.html)
返回结果需要是string类型(比如#root.methodName就是,#root.method不是String),通用办法是重写keyGenerator定制Key默认生成策略(按照缓存名称+id方式生成key,同时确保更新操作的时候,操作的是同一条数据),也可以在使用缓存注解时指定key:
- /**
- * 指定key的生成策略
- * @return KeyGenerator
- */
- @Bean public KeyGenerator keyGenerator() {
- return new KeyGenerator() {
- @Override public Object generate(Object target, Method method,
- Object... params) {
- StringBuilder sb = new StringBuilder();
- String[] value = new String[1];
- // sb.append(target.getClass().getName());
- // sb.append(":" + method.getName());
- Cacheable cacheable = method.getAnnotation(Cacheable.class);
- if (cacheable != null) {
- value = cacheable.value();
- }
- CachePut cachePut = method.getAnnotation(CachePut.class);
- if (cachePut != null) {
- value = cachePut.value();
- }
- CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
- if (cacheEvict != null) {
- value = cacheEvict.value();
- }
- sb.append(value[0]);
- //获取参数值
- for (Object obj : params) {
- sb.append(":" + obj.toString());
- }
- return sb.toString();
- }
- };
- }
注意:
1,在使用缓存注解时,也可以指定统一规则的key
(比如:@Cacheable(value = "catCache", key = "#root.caches[0].name + ':' + #id"));
就可以不走KeyGenerator默认规则;同样可以实现,更新和查询都是同一个key的数据;
2,使用注解进行数据缓存,指定数据过期时间需要百度普及下!
4, 更新缓存数据
更新与删除Redis缓存需要用到@cacheput和@cacheevict。必须保证keyGenerator生成同一个key,否则更新的不是同一条的数据;
- /**
- * 更新redis中的缓存数据
- *</br> #root. 是spEL表达式
- * </br>如果参数是个对象,就通过“#对象.变量”获取到对应的key中需要的值;比如:#cat.id
- * @param id 主键
- */
- @CachePut(value = "catCache", key = "#root.caches[0].name + ':' + #id")
- @RequestMapping(value = "/updateCat", method = RequestMethod.POST)
- @ResponseBody
- public Cat update(@RequestParam int id){
- System.out.println("==========请求参数:"+id);
- return this.catService.updateCat(id);
- }
-
-
- 本文转自 wyait 51CTO博客,原文链接:http://blog.51cto.com/wyait/2048478,如需转载请自行联系原作者
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。