redistemplate opsforvalue和boundValueOps
什么是spring-data-redis
spring-data-redis是spring-data模块的一部分,专门用来支持在spring管理项目对redis的操作,使用java操作redis最常用的是使用jedis,但并不是只有jedis可以使用,像jdbc-redis,jredis也都属于redis的java客户端,他们之间是无法兼容的,如果你在一个项目中使用了jedis,然后后来决定弃用掉改用jdbc-redis就比较麻烦了,spring-data-redis提供了redis的java客户端的抽象,在开发中可以忽略掉切换具体的客户端所带来的影响,而且他本身就属于spring的一部分,比起单纯的使用jedis,更加稳定.管理起来更加自动化.(当然jedis的缺点不止以上).
spring-data-redis的特性
1.自动管理连接池,提供了一个高度封装的RedisTemplate类
2.针对jedis客户端的大量api进行了归类封装,把同一类型的操作封装成了Operation接口.支持redis中的五种数据类型的操作.
3.针对数据的"序列化与反序列化",提供了多种可以选择的策略(RedisSerializer)
JdkSerializationRedisSerializer:当需要存储java对象时使用.
StringRedisSerializer:当需要存储string类型的字符串时使用.
JacksonJsonRedisSerializer:将对象序列化成json的格式存储在redis中,需要jackson-json工具的支持,(目前我还没使用过,不了解)
Operations
redisTemplate有两个方法经常用到,一个是opsForXXX一个是boundXXXOps,XXX是value的类型,前者获取到一个Opercation,但是没有指定操作的key,可以在一个连接(事务)内操作多个key以及对应的value;后者会获取到一个指定了key的operation,在一个连接内只操作这个key对应的value.
ValueOperation和BoundValueOperation
ValueOperations valueOperations = redisTemplate.opsForValue();
BoundValueOperations<String, User> boundValueOps = redisTemplate.boundValueOps("key");
ValueOperation可以缓存Integer,String,java对象等类型.使用.set(key,value)方法进行设置,get(key)方法用来获取.
同样的方式可以获取ListOperations对象,可以用来缓存List,此外还有SetOperation,HashOperation
在spring+springmvc项目中使用spring-data-redis
1.maven配置,添加pom依赖
1 <dependency> 2 <groupId>org.springframework.data</groupId> 3 <artifactId>spring-data-redis</artifactId> 4 <version>1.3.4.RELEASE</version> 5 </dependency> 6 7 <dependency> 8 <groupId>redis.clients</groupId> 9 <artifactId>jedis</artifactId> 10 <version>2.4.2</version> 11 </dependency>
2.spring-redis.xml配置:
<!--JedisPoolConfig 连接池参数配置--> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!--最大空闲实例数--> <property name="maxIdle" value="300" /> <!--最大活跃实例数--> <property name="maxTotal" value="600" /> <!--创建实例时最长等待时间--> <property name="maxWaitMillis" value="1000" /> <!--创建实例时是否验证--> <property name="testOnBorrow" value="true" /> </bean><span style="color: #008000;"><!--</span><span style="color: #008000;">JedisConnectionFactory 跟配置数据库连接池类似,需要配置JedisConnectionFactory来通过服务器或者连接池的方式获取redis服务器的连接</span><span style="color: #008000;">--></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">bean </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="connectionFactory"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"</span><span style="color: #0000ff;">></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="hostName"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="127.0.0.1"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="port"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="6379"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="usePool"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="poolConfig"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="poolConfig"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"></</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">bean </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="stringRedisSerializer"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="org.springframework.data.redis.serializer.StringRedisSerializer"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">bean </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="valueSerializer"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"</span><span style="color: #0000ff;">/></span> <span style="color: #008000;"><!--</span><span style="color: #008000;"> redis模板配置 spring-data-redis提供了一个基础的泛型RedisTemplate封装了基础的crud操作</span><span style="color: #008000;">--></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">bean </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="redisTemplate"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="org.springframework.data.redis.core.RedisTemplate"</span><span style="color: #0000ff;">></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="connectionFactory"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="connectionFactory"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="defaultSerializer"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="stringRedisSerializer"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="keySerializer"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="stringRedisSerializer"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="valueSerializer"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="valueSerializer"</span><span style="color: #0000ff;">/></span> <span style="color: #0000ff;"></</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">></span></pre>
以上配置完成后,就可以使用spring-data-redis了,为了演示一下具体的使用,这里接着写一个简单地demo.
3.创建实体类User
1 public class User implements Serializable { 2 3 private static final long serialVersionUID = 1L; 4 5 /** 用户ID */ 6 private Long id; 7 8 /** 用户名 */ 9 private String name; 10 11 /** 用户年龄 */ 12 private Integer age; 13 }
注意:如果需要向redis内存储pojo对象,那么该对象必须要实现Serializable接口,因为在redis中存储pojo类仍然存储的是string,它会把数据转化成byte[]数组的形式,在存取的时候就要对数据格式进行转化,就涉及到了序列化与反序列化.
4.创建UserCcontroller
@Controller public class UserController extends BaseController {@Autowired </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> IUserService userService; @Autowired </span><span style="color: #0000ff;">private</span> RedisTemplate<String,User><span style="color: #000000;"> redisTemplate; @ResponseBody @RequestMapping(</span>"/redis"<span style="color: #000000;">) </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Object redis() { User u1</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> User(); u1.setId(</span>1L<span style="color: #000000;">); u1.setName(</span>"wang"<span style="color: #000000;">); u1.setAge(</span>22<span style="color: #000000;">); redisTemplate.opsForValue().set(</span>"user:wang"<span style="color: #000000;">,u1); User u2</span>=redisTemplate.opsForValue().get("user:wang"<span style="color: #000000;">); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> u2; }
}
这里我们将user对象存储到redis中,再读出来,运行项目,测试这个接口,就可以在浏览器中看到json格式的user对象.
常见报错及解决方案
最开始我测试spring-data-redis的功能是从一个空项目一点点配置的,启动时报了很多异常,下面一个一个来.
1.启动tomcat报错
Caused by: java.lang.VerifyError: (class: org/springframework/data/redis/connection/jedis/JedisConnectionFactory,
method: afterPropertiesSet signature: ()V) Incompatible argument to function
原因及解决方案:
在pom中我最开始配置的jedis版本是2.7.3,spring-data-redis版本是1.1.1,网上搜索了一翻,发现有一个说法是jedis-2.7.3.jar 和 spring-data-redis-1.1.1.RELEASE.jar 无法搭配使用,于是我把spring-data-redis的版本设成比较高的1.3.4,重新部署,果然此问题解决,紧接着问题又来了.
2.启动tomcat报错
Caused by: Java.lang.NoSuchMethodError: redis.clients.jedis.JedisShardInfo.setTimeout(I)V
原因及解决方案:同样是版本的问题(没错,都被我撞上了),jedis版本是2.7.3,太高了,改成2.4.3以后,问题解决.
3.启动tomcat报错
java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
原因及解决方案:这个GenericObjectPool使用到了commons-pool.jar中的类,我们的依赖中没有这个jar,所以添加commons-pool的dependency即可.
4.运行接口报错
HTTP Status 500 - Request processing failed; nested exception is java.lang.ClassCastException: com.baomidou.springmvc.model.system.User cannot be cast to java.lang.String
原因及解决方案:在spring-redis配置文件中的redisTemplate的property中缺少name="valueSerializer"的配置,因为存储在redis的value是user对象,需要使用JdkSerializationRedisSerializer对象进行对象的序列化操作,解决方案就是配置成上面spring-redis.xml的方式.
<div id="blog_post_info">
<div class="clear"></div>
<div id="post_next_prev">
<a href="https://www.cnblogs.com/fingerboy/p/6657118.html" class="p_n_p_prefix">« </a> 上一篇: <a href="https://www.cnblogs.com/fingerboy/p/6657118.html" title="发布于 2017-04-05 14:42">优雅高效的MyBatis-Plus工具快速入门使用</a>
<br>
<a href="https://www.cnblogs.com/fingerboy/p/6768874.html" class="p_n_p_prefix">» </a> 下一篇: <a href="https://www.cnblogs.com/fingerboy/p/6768874.html" title="发布于 2017-04-27 10:32">java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口</a>
</div><!--end: topics 文章、评论容器-->
</div>
<span id="comment-maxId" style="display:none">3667951</span>
<span id="comment-maxDate" style="display:none">2017/4/14 下午12:29:31</span>
2017-04-14 12:29
<a id="a_comment_author_3667951" href="https://home.cnblogs.com/u/1026854/" target="_blank">黄百鸣灵</a>
</div>
<div class="feedbackCon">
</div>
</div>
<div id="sideBar">
<div id="sideBarMain">
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
28 | 29 | 30 | 1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
26 | 27 | 28 | 29 | 30 | 31 | 1 | |||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
<div id="leftcontentcontainer">
<div id="blog-sidecolumn">
-
</li> <li>
2.趣谈编程史第4期-饱受争议的前端之王JavaScript的血泪成长史
</li> <li>
3.趣谈编程史第2期-这个世界缺少对C语言的敬畏,你不了解的C语言科普
</li> <li>
4.趣谈编程史第1期-跌宕起伏的java帝国史,剖析谷歌甲骨文长达8年的版权战争
</li> <li>
</li> <li>
6.多线程学习笔记-深入理解ThreadPoolExecutor
</li> <li>
7.使用CompletableFuture优化你的代码执行效率
</li> <li>
</li> <li>
9.Guava Cache探索及spring项目整合GuavaCache实例
</li> <li>
10.将List按照指定大小等分的几种实现方式和效率对比及优化
</li>
随笔分类
(18)
学习笔记(18)</h3> <ul> <li>
</li> </ul> </div> <div id="sidebar_postarchive" class="catListPostArchive sidebar-block"> <h3 class="catListTitle">
随笔档案
(132)
2020年3月(2)</h3> <ul> <li>
2020年1月(2)</li> <li>
2019年10月(1)</li> <li>
2019年1月(1)</li> <li>
2018年11月(2)</li> <li>
2018年9月(1)</li> <li>
2018年7月(1)</li> <li>
2018年6月(1)</li> <li>
2017年12月(1)</li> <li>
2017年11月(1)</li> <li>
2017年8月(2)</li> <li>
2017年6月(1)</li> <li>
2017年5月(1)</li> <li>
2017年4月(3)</li> <li>
2017年2月(3)</li> <li>
2017年1月(2)</li> <li>
2016年12月(1)</li> <li>
2016年11月(6)</li> <li>
2016年10月(3)</li> <li>
2016年7月(4)</li> <li>
2016年5月(6)</li> <li>
2016年4月(14)</li> <li>
2016年3月(39)</li> <li>
2016年2月(20)</li> <li>
2016年1月(13)</li> <li>
2015年9月(1)</li> <li>
</li> </ul> </div>
- 2. Re:Myeclipse中导入项目后java类中汉字注释出现乱码问题(已解决)
改了,还是不行。
- 3. Re:c3p0数据库连接池的使用详解
- @wilson_hz 你这也不是正确的吧?每次调用getConnection都是获取同一个连接对象,这还能算连接池吗?博主的代码每次获取连接都要设置数据库信息,所以也不太对,但起码算是连接池,我认为应...
- 4. Re:编程史话第四期-饱受争议的前端之王JavaScript的血泪成长史
写的很棒,拜读了
- 5. Re:趣谈编程史第2期-这个世界缺少对C语言的敬畏,你不了解的C语言科普
- 来自java开发人员鼓掌。
</div><!--end: sideBarMain --> </div><!--end: sideBar 侧边栏容器 --> <div class="clear"></div> </div><!--end: main --> <div class="clear"></div> <div id="footer"> <!--done-->
Copyright © 2020 冬至饮雪
Powered by .NET Core on Kubernetes</div><!--end: footer -->