Spring Boot 中使用 Redis
Redis 环境
redis 安装、配置,启动:(此处以云服务器上进行说明)
下载地址:https://redis.io/download/
下载后上传到云服务器上,如 /usr/local 中
gcc 环境安装:yum install -y gcc-c++
解压:tar -zxvf xxx
进入解压后的 redis 目录下执行
编译:make
安装:make install
下载 redis/bin/redis.conf 进行下列配置后上传覆盖原文件:
1. 注释掉 bind 127.0.0.1
2. 设置 protected-mode 为 no
3. 建议设置密码 requirepass xxx
在 redis/bin 下执行命令使用配置文件方式后台启动 redis:
./redis-server redis.conf &
查看 redis 启动状态:
ps -ef|grep redis
其他:
关闭 redis:redis-cli shutdown
连接问题参考:
1. 终端执行,防火墙放行:firewall-cmd --zone=public --add-port=6379/tcp --permanent
2. 终端执行,防火墙重启:firewall-cmd --reload
3. 云服务器端口开放问题:在实例-》安全组管理中开放 6379 端口
Spring Boot 中使用 Redis
1. 添加 pom
<!-- spring-boot-starter-data-redis 若需要指定版本号自行 maven 仓库中找 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 添加配置
spring:
redis:
database: 0
host: xxxxx # Redis服务器地址,修改为你的地址
port: 6379 # Redis服务器连接端口
password: xxxxx # Redis服务器连接密码(默认为空)
timeout: 3000 # Redis服务器链接超时配置
3. 导入 redis 工具类
PS:redis 工具类对常用操作进行了封装,可自行研究食用。
/**
* Redis 工具类
*/
@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, Object> redisTemplate;
// public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
// this.redisTemplate = redisTemplate;
// }
/**
* 指定缓存失效时间
*
* @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((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
//============================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 锁住的key
* @param lockExpireMils 锁住的时长。如果超时未解锁,视为加锁线程死亡,其他线程可夺取锁
* @return
*/
public boolean setNx(String key, Long lockExpireMils) {
// new RedisCallback<>() {
// @Override
// public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
// return null;
// }
// };
return (boolean) redisTemplate.execute((RedisCallback) connection -> {
//获取锁
/*
setNX(k,v):如果该键不存在,则设置该键的值为指定的字符串;否则不做任何事情;
使用 setNX() 命令可以实现分布式锁等功能,因为该命令在设置键值对时是具有原子性的。
在多线程或多进程环境中,如果多个线程或进程同时尝试使用 setNX() 命令来设置同一个键,
只有一个线程或进程能够成功地设置,其他线程或进程会失败,从而实现了互斥操作。
*/
return connection.setNX(key.getBytes(), String.valueOf(System.currentTimeMillis() + lockExpireMils + 1).getBytes());
});
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
// 将指定 key 的值增加 delta。如果 key 不存在,则会先创建一个初始值为 0 的 key,然后再执行增加操作。
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 item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
//============================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 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;
}
}
/**
* 模糊查询获取key值
*
* @param pattern
* @return
*/
public Set keys(String pattern) {
return redisTemplate.keys(pattern);
}
/**
* 使用Redis的消息队列
*
* @param channel
* @param message 消息内容
*/
public void convertAndSend(String channel, Object message) {
redisTemplate.convertAndSend(channel, message);
}
//=========BoundListOperations 用法 start============
/**
* 将数据添加到Redis的list中(从右边添加)
*
* @param listKey
* @param timeout 有效时间
* @param unit 时间类型
* @param values 待添加的数据
*/
public void addToListRight(String listKey, long timeout, TimeUnit unit, Object... values) {
//绑定操作
BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
//插入数据
boundValueOperations.rightPushAll(values);
//设置过期时间
boundValueOperations.expire(timeout, unit);
}
/**
* 根据起始结束序号遍历Redis中的list
*
* @param listKey
* @param start 起始序号
* @param end 结束序号
* @return
*/
public List<Object> rangeList(String listKey, long start, long end) {
//绑定操作
BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
//查询数据
return boundValueOperations.range(start, end);
}
/**
* 弹出右边的值 --- 并且移除这个值
*
* @param listKey
*/
public Object rightPop(String listKey) {
//绑定操作
BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
return boundValueOperations.rightPop();
}
//=========BoundListOperations 用法 End============
}
4. 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Resource
private RedisUtil redisUtil;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Test
public void test_redis_util() {
boolean flag = redisUtil.set("key", "value");
String v = (String) redisUtil.get("key");
System.out.println("flag = " + flag + " v = " + v);
}
@Test
public void test_redisTemplate() {
ValueOperations<String, Object> ops = redisTemplate.opsForValue();
ops.set("k1", "v1");
System.out.println(ops.get("k1"));
}
}
Spring Boot 中使用 Redis的更多相关文章
- spring boot 中使用redis session
spring boot 默认的httpsession是存在内存中.这种默认方式有几个缺点:1.当分布式部署时,存在session不一致的问题:2.当服务重启时session就会丢失,这时候用户就需要重 ...
- Spring Boot中使用Redis小结
Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, 等. Redis简单介绍 Redi ...
- Spring Boot中使用redis的发布/订阅模式
原文:https://www.cnblogs.com/meetzy/p/7986956.html redis不仅是一个非常强大的非关系型数据库,它同时还拥有消息中间件的pub/sub功能,在sprin ...
- Spring Boot 中集成 Redis 作为数据缓存
只添加注解:@Cacheable,不配置key时,redis 中默认存的 key 是:users::SimpleKey [](1.redis-cli 中,通过命令:keys * 查看:2.key:缓存 ...
- spring boot 中使用 Redis 与 Log
spring boot + mybatis + redis 配置 1.application.yml #配置访问的URLserver: servlet-path: /web port: spring: ...
- Spring Boot中使用Redis数据库
引入依赖 Spring Boot提供的数据访问框架Spring Data Redis基于Jedis.可以通过引入spring-boot-starter-redis来配置依赖关系. <depend ...
- 学习Spring Boot:(十七)Spring Boot 中使用 Redis
前言 Redis 1 是一个由Salvatore Sanfilippo写的key-value存储系统. edis是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日 ...
- Spring Boot中使用Redis
一.定义工程 创建一个spring boot模块 二.修改pom文件 在pom文件中添加Spring Boot与Redis整合依赖 <dependencies> <!--spring ...
- spring boot中集成Redis
1 pom.xml文件中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <arti ...
- 【redis】spring boot中 使用redis hash 操作 --- 之 使用redis实现库存的并发有序操作
示例: @Autowired StringRedisTemplate redisTemplate; @Override public void dealRedis(Dealer dealer) { d ...
随机推荐
- C语言初级阶段6——自定义数据类型
C语言初级阶段6--自定义数据类型 阐述 1.构造数据类型:用户自己建立的数据类型(自定义数据类型). 2.C语言中的自定义数据类型:数组类型.结构体类型.共用体类型和枚举类型. 结构体 1.定义:C ...
- C语言初级阶段5——函数2
C语言初级阶段5--函数2 址传递 1.地址:在定义变量,数组,函数等等,系统会自动给分配他们的内存区域(地址),把这个数据放到这个地址上面. 2.&:&a 得到a的地址编号 3.*: ...
- python2 selenium
参考blog: https://www.cnblogs.com/xiaozhiblog/p/5378723.html http://www.cnblogs.com/fnng/ 一.项目结构介绍 下面逐 ...
- 解决idea翻译失败问题
修改host(windows)(2022-11-09) 进入该目录,C:\Windows\System32\drivers\etc,hosts文件上右键,把hosts文件的只读去了 打开hosts文件 ...
- VMware安装Rocky Linux8服务器系统并执行优化,包括修改安装镜像源、ssh免密等等
1. https://blog.csdn.net/DCTANT/article/details/125430461?utm_medium=distribute.pc_relevant.none-tas ...
- conda Installing on Linux - 搬运
转自:Installing on Linux - conda 23.1.0 documentation Installing on Linux Download the installer: Min ...
- Python学习笔记-argparse模块
Python学习笔记-argparse模块 optparseargparse 昨天学习了一个简单的端口扫描器的脚本,其中涉及到了optparse模块,网上关于此模块的介绍已有很多,但这个模块已经不更新 ...
- Matlab - 在Figure界面去掉图像的坐标刻度
Matlab版本:2018b 经过一番尝试,发现有两种方法 第一种:修改坐标轴的Visible属性,去掉坐标轴数字和坐标轴标签 第二种:删除Tick,只去掉坐标轴数字 第一种 ①原图 ②如果有多个子图 ...
- linux内存管理之malloc、kmalloc、kzalloc、vmalloc的区别
1 用户空间申请内存的方式 1.1 函数原型 void *malloc(unsigned int num_bytes): 1.2 函数解释和说明 如果分配成功则返回指向被分配内存的指针(此存储区中的初 ...
- mfc edit只允许输入数字
1.给EDIT控件添加 EN_CHANGE 事件 2.事件中的代码如下: 1 CString strEditVidoe; 2 GetDlgItem( iId )->GetWindowText( ...