spring-boot-route(十二)整合redis做为缓存
redis简介
redis作为一种非关系型数据库,读写非常快,应用十分广泛,它采用key-value的形式存储数据,value常用的五大数据类型有string(字符串),list(链表),set(集合),zset(有序集合)和hash(哈希表)。
redis的特性决定了它的功能,它可以用来做以下这些事情!
- 排行榜,利用zset可以方便的实现排序功能
- 计数器,利用redis中原子性的自增操作,可以统计到阅读量,点赞量等功能
- 简单消息队列,list存储结构,满足先进先出的原则,可以使用lpush/rpop或rpush/lpop实现简单消息队列
- session共享,分布式系统中,可以利用redis实现session共享。spring官方提供的分布式解决方案Spring Session就是利用redis 实现的。
Spring Boot对redis也实现自动化装配,使用非常方便。
Spring Boot整合redis
1. 引入redis依赖
<dependencies>
<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>
</dependencies>
2. 配置redis相关信息
spring:
redis:
# redis库
database: 0
# redis 服务器地址
host: localhost
# redis 端口号
port: 6379
# redis 密码
password:
# 连接超时时间(毫秒)
timeout: 1000
lettuce:
pool:
# 连接池最大链接数(负数表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(负数表示没有限制)
max-wait: -1
# 连接池最大空闲连接数
max-idle: 8
# 连接池最小空闲连接数
min-idle: 0
3. 操作redis
SpringBoot提供了两个bean来操作redis,分别是RedisTemplate
和 StringRedisTemplate
,这两者的主要区别如下。
RedisTemplate
使用的是JdkSerializationRedisSerializer
存入数据会将数据先序列化成字节数组然后在存入Redis数据库。
StringRedisTemplate
使用的是StringRedisSerializer。
下面一起来看看效果:
@RestController
public class RedisDemo {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("redisTmeplateData")
public void redisTemplateData(){
redisTemplate.opsForValue().set("name","Java旅途");
}
@GetMapping("stringRedisTemplateData")
public void stringRedisTemplateData(){
stringRedisTemplate.opsForValue().set("desc","坚持分享java技术栈");
}
}
第一个方法存入的数据如下图:
第二个方法存入的数据如下图:
由于RedisTemplate是序列化成字节数组存储的,因此在redis客户端的可读性并不好。
自动缓存
@Cacheable
可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。
如果添加了@Cacheable
注解,那么方法被调用后,值会被存入redis,下次再调用的时候会直接从redis中取值返回。
@GetMapping("getStudent")
@Cacheable(value = "student:key")
public Student getStudent(){
log.info("我不是缓存,我是new的对象!");
Student student = new Student("Java旅途",26);
return student;
}
记得要开启缓存,在启动类加上@EnableCaching
注解
访问上面的方法,如果不打印日志,则是从缓存中获取的值。
封装redisUtils
RedisTemplate提供了很多方法来操作redis,但是找起来比较费事,为了更好的操作redis,一般会封装redisUtils来满足业务开发。这里简单封装几个做个示例,如果开发中有需求可以自己封装。
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
/**
* 普通存入
* @param key
* @param value
* @return
*/
public boolean set(String key,Object value){
try {
redisTemplate.opsForValue().set(key,value);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 普通获取key
* @param key
* @return
*/
public Object get(String key){
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 存入key,设置过期时长
* @param key
* @param value
* @param time
* @return
*/
public boolean set(String key,Object value,long time){
try {
if(time > 0){
redisTemplate.opsForValue().set(key,value,time, TimeUnit.SECONDS);
}else{
redisTemplate.opsForValue().set(key,value);
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 判断key是否存在
* @param key
* @return
*/
public boolean exists(String key){
try {
return redisTemplate.hasKey(key);
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 删除key
* @param key
*/
public void del(String key){
try {
if(key != null && key.length() > 0){
redisTemplate.delete(key);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
< END >
此是spring-boot-route系列的第十二篇文章,这个系列的文章都比较简单,主要目的就是为了帮助初次接触Spring Boot 的同学有一个系统的认识。本文已收录至我的github
,欢迎各位小伙伴star
!点击文末的阅读原文即可到达github
仓库!
github:https://github.com/binzh303/spring-boot-route
- React多页面应用6(gulp自动化发布到多个环境、生成版本号、压缩成zip等)
- SDIBT 1046 Primary Arithmetic
- 洛谷P2415 集合求和
- React多页面应用5(webpack生产环境配置,包括压缩js代码,图片转码等)
- SDIBT 1046 Primary Arithmetic
- React多页面应用4(webpack自动化生成多入口页面)
- 第二周神经网络基础2.1 二分分类2.2 logistic回归2.3 logistic 回归损失函数2.4 梯度下降2.5 导数2.14 向量化logistic 回归的输出2.15 Python中的广
- 1031 SDIBT Where's Waldorf?
- poj 2469 Stack 'em Up
- React多页面应用3(webpack性能提升,包括打包性能、提取公共包等)
- POJ 2646 The Trip
- React多页面应用2(处理CSS及图片,引入postCSS,及图片处理等)
- 图的广度优先搜索和深度优先搜索(邻接链表表示)邻接链表广度优先搜索深度优先搜索运行结果
- JOJ 2680 Problem F: Coin Game
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法