Redis简介

Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API非关系型数据库(NoSQL)

Redis的特性

  1. Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  2. 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  3. 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  4. 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

Redis的应用

  1. 会话缓存
  2. 数据缓存
  3. 排行榜/计数器
  4. 消息队列

Redis的数据类型

  • String: 字符串
  • Hash: 散列
  • List: 列表
  • Set: 集合
  • Sorted Set: 有序集合

Redis的部署

PS: 我这里是基于Mac环境,Windows环境下的同学可以安装Linux虚拟机同步进行操作。

  1. 官网下载 Stable(稳定)版本

  1. 找到下载的文件,解压并编译
tar -zxvf redis-5.0.4.tar.gz
mv redis-5.0.4 /usr/local/
cd /usr/local/redis-5.0.4/
make test

执行到这里,最好先执行一遍make test,确保编译可以通过,需要大概三分钟。

到这个就说明测试通过了。我们接着往下执行

make
cd src/
make install

执行到这里安装就算是告一段落了,接下来我们进行redis的一些配置:

vim ../redis.conf

找到136行左右的daemonize将其属性改为yes,可以让redis在后台运行,然后找到500行左右的requirepass,后面输入我们需要设置的密码,这样就可以通过密码来访问redis了。

然后我们通过指定配置文件的方式来启动redis

./redis-server ../redis.conf

执行完事儿之后,查看是否执行成功:

ps -ef | grep redis

可以看到,我们的redis已经启动成功了,然后通过rdm来访问一下:

大功告成,现在万事俱备,只欠东风。我们下面来看一下在Spring Boot中怎么使用redis吧。

在Spring Boot中的使用

Spring Boot给我们提供了现成的spring-boot-starter-data-redis,我们只需要在pom文件中将之导入即可。

		<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>

然后,我们需要在配置文件中配置一些有关redis的信息:

spring:
redis:
host: 127.0.0.1 # IP
port: 6379 # 端口号
password: 123456 # 密码
lettuce:
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接

接下来,我们需要对我们所需要的Redis的操作给封装到一个接口中,方便我们去调用,这里我基于接口,抽象类,实现类的结构实现了一套Redis的方法,需要的同学可以去GitHub上下载(子项目名称:viboot-rds),GitHub的地址在文末。这里仅仅贴出接口的部分方法

package com.itframe.dao;

import java.util.List;
import java.util.Map;
import java.util.Set; /**
*
*/
public interface RedisDao { /**
* 判断缓存中是否有对应的value
*
* @param key
* @return boolean
*/
public boolean existsKey(Object key); /**
* 根据key获取key列表(key值可为模糊匹配---taskInfo:taskDetail:* <---> *代表任意字符)
*
* @param pattern
* @return Set<Object>
*/
public Set<Object> keys(Object pattern); /**
* 根据key删除对应的value
*
* @param key
*/
public boolean delete(Object key); /**
* 根据key获取个数
*
* @param key
*/
public int count(Object key); /**
* 批量删除对应的value
*
* @param keys
*/
public void delete(String[] keys); /**
* 批量删除key(key值可为模糊匹配---taskInfo:taskDetail:* <---> *代表任意字符)
*
* @param pattern
*/
public long deletePattern(Object pattern); /**
* 批量删除对应的value
*
* @param keys
*/
public long delete(Set<Object> keys); /**
* 写入缓存(操作字符串)
*
* @param key
* @param value
* @return boolean
*/
public boolean vSet(Object key, Object value); /**
* 写入缓存设置时效时间(操作字符串)
*
* @param key
* @param value
* @return boolean
*/
public boolean vSet(Object key, Object value, Long expireTime); /**
* 更新写入缓存设置时效时间(操作字符串)
*
* @param key
* @return boolean
*/
public boolean vSetUpdate(Object key, Long expireTime); /**
* 读取缓存(操作字符串)
*
* @param key
* @return Object
*/
public Object vGet(Object key); /**
* 哈希 添加(操作hash)
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(Object key, Object hashKey, Object value); /**
* 哈希 添加(操作hash)
*
* @param key
* @param map
*/
public void hmSetAll(Object key, Map<Object, Object> map); /**
* 哈希获取数据(操作hash)
*
* @param key
* @return Map<Object, Object>
*/
public Map<Object, Object> hmGet(Object key); /**
* 哈希获取数据(操作hash)
*
* @param key
* @param hashKey
* @return Object
*/
public Object hmGet(Object key, Object hashKey); /**
* 哈希删除数据(操作hash)
*
* @param key
* @param hashKey
* @return Object
*/
public Object hmDel(Object key, Object hashKey); }

抽象类中我们进行了RedisTemplate的初始化以及序列化:

public abstract class AbstractBaseRedisDao<K, V> {

	@Resource(name = "redisTemplate")
protected RedisTemplate<K, V> redisTemplate; /**
* 设置redisTemplate
*
* @param redisTemplate
*/
public void setRedisTemplate(RedisTemplate<K, V> redisTemplate) {
this.redisTemplate = redisTemplate;
} /**
* 获取 RedisSerializer
*/
protected RedisSerializer<String> getRedisSerializer() {
return redisTemplate.getStringSerializer();
}
}

在实现类中我们通过操作RestTemplate来实现接口中的方法~

Redis缓存实战

首先,我们如果想在Spring Boot项目中启用缓存,需要在启动类上加上注解@EnableCaching,这个是重点,要记住了!

首先介绍一下注解三剑客:@Cacheable @CachePut@CacheEvict

  • @Cacheable:主要针对方法配置,能够根据方法的请求参数对其进行缓存,常用于查询操作
  • @CachePut:主要针对方法配置,能够根据方法的请求参数对其进行缓存,常用于修改操作
  • @CacheEvict:清空缓存,主要用于删除操作。

下面我们来看一下用法:


/**
* value: 缓存的名称
* key: 缓存的键
* return 缓存的值
*/
@Override
@Cacheable(value = "users", key = "#id")
public UserDO findOne(Long id) {
// 如果我们第二次访问的时候,控制台没有打印出这句话说明是从缓存中取出
log.info("From MYSQL");
return userMapper.get(id);
} @Override
@CachePut(value = "users", key = "#userDO.id")
public UserDO update(UserDO userDO) {
// 执行之后,再次访问findOne的时候,应当没有打印出“From MySQL”,且返回的是我们修改后的值,说明这一步缓存成功
if (userMapper.update(userDO) > 0) {
return userMapper.get(userDO.getId());
}
return null;
} @Override
@CacheEvict(value = "users", key = "#id")
public int delete(Long id) {
// 执行之后去rdm中查看即可
return userMapper.delete(id);
}

测试1

第一次访问findOne

第二次访问findOne:

仍然是刚刚的结果,但是控制台没有打印出任何东西,说明缓存成功


测试2

调用update后再次调用findOne:

可以看出信息已被修改且未访问数据库


测试3

访问delete,查看rdm:

说明删除成功~

源码地址

Github

Gitee

记得顺手点个star,您的肯定是对我写作最大的动力!

公众号

原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知

Spring Boot 2.x(十四):整合Redis,看这一篇就够了的更多相关文章

  1. Spring Boot 2.X(十四):日志功能 Logback

    Logback 简介 Logback 是由 SLF4J 作者开发的新一代日志框架,用于替代 log4j. 主要特点是效率更高,架构设计够通用,适用于不同的环境. Logback 分为三个模块:logb ...

  2. Spring Boot(十三):整合Redis哨兵,集群模式实践

    前面的两篇文章(Redis的持久化方案, 一文掌握Redis的三种集群方案)分别介绍了Redis的持久化与集群方案 -- 包括主从复制模式.哨兵模式.Cluster模式,其中主从复制模式由于不能自动做 ...

  3. SpringBoot进阶教程(二十四)整合Redis

    缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非 ...

  4. spring boot 常见三十四问

    Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家. 问题一 Spring Boot.Spring MVC 和 Spring 有什么区别 ...

  5. 【Spring Boot学习之十】整合Dubbo

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 参考以下两篇文章,总结的很全面: springboot整合最新版dubbo以及dubbo-admin的安装使用Spri ...

  6. Spring Boot系列教程十四:Spring boot同时支持HTTP和HTTPS

    自签证书 openssl生成服务端证书,不使用CA证书直接生成 -in server.csr -signkey server.key -out server.crt # 5.server证书转换成ke ...

  7. Spring Boot教程(十四)快速入门

    快速入门 本章主要目标完成Spring Boot基础项目的构建,并且实现一个简单的Http请求处理,通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单.开发快速的特性. 系统要求: ...

  8. 学习Spring Boot:(十四)spring-shiro的密码加密

    前言 前面配置了怎么使用 shiro ,这次研究下怎么使用spring shiro的密码加密,并且需要在新增.更新用户的时候,实现生成盐,加密后的密码进行入库操作. 正文 配置凭证匹配器 @Bean ...

  9. redis看这一篇就够了

    redis的下载安装 准备相关依赖 yum install gcc 下载安装包 # 切换到存放安装包到目录 cd /usr/local # 下载安装包 wget http://download.red ...

  10. SpringBoot进阶教程(二十六)整合Redis之共享Session

    集群现在越来越常见,当我们项目搭建了集群,就会产生session共享问题.因为session是保存在服务器上面的.那么解决这一问题,大致有三个方案,1.通过nginx的负载均衡其中一种ip绑定来实现( ...

随机推荐

  1. TypeScript 函数-函数类型

    //指定参数类型 function add(x:number,y:number){ console.log("x:"+x); // reutrn(x+y); } //指定函数类型 ...

  2. 解决audio控制播放音量

    在写手机端项目时,可能会遇到使用audio播放音乐,那么怎样控制audio默认播放的音量呢?下面时解决办法 volume 属于是控制audio 播放音乐的音量,其范围0-1,1表示音量最大 getVi ...

  3. php解析ini,conf文件

    /** * 解析conf文件,类似ini文件 * @param string $strFileName 文件名 * @param boolean $boolParseVal 解析值为数组,多 * @a ...

  4. 微信小程序----没有 DOM 对象,一切基于组件化 ---- mpvue

    封装好用的 类库 和 组件,复用且灵活度高 抽取相同的部分放在函数内部(组件内部) 抽取不同的部分放在形参(组件 props 传参,或者插槽) new Promise 运行时 初始化实例对象的状态为 ...

  5. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.e3mall.search.mapper.ItemMapper.getItemList

    java.lang.RuntimeException: org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...

  6. sv时序组合和时序逻辑

    input a; input b; input c; reg d; wire e; reg f; // 时序逻辑,有寄存器 always@(posedge clk)begin 'b1)begin d ...

  7. python从入门到实践-4章操作列表

    magicians = ['alice','david','carolina']for magician in magicians: print(magician) print(magician.ti ...

  8. dc的博客翻修计划启动

    紫书大部分学习完毕,等待一轮补完计划: 白书正在攻略中,进度百分之30: 博客翻修计划启动,我会在本学期内逐渐写系统性的学习笔记,我学习时遇到的困难的地方会有说明: 每个部分一定会放上经过验证的实现: ...

  9. week01-绪论

    一.作业题目 仿照三元组或复数的抽象数据类型写出有理数抽象数据类型的描述 (有理数是其分子.分母均为整数且分母不为零的分数).           有理数基本运算: 构造有理数T,元素e1,e2分别被 ...

  10. 原生JS实现下拉刷新

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...