文章目录
Jedis
Jedis 是 Redis 官方推荐的 Java 连接工具。
导入依赖
</dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
测试连接
package com.zk.jedis;
import redis.clients.jedis.Jedis;
public class TestJedis {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.ping());
}
}
输出:
PONG
Jedis 实现事务
执行成功:
package com.zk.jedis;
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class TestJedis {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "xiaoming");
jsonObject.put("num", "24");
String result = jsonObject.toJSONString();
// 开启事务
Transaction multi = jedis.multi();
try{
multi.set("user1", result);
multi.set("user2", result);
// 执行事务
multi.exec();
}catch (Exception e){
// 失败就放弃事务
multi.discard();
}finally {
// 关闭事务
multi.close();
}
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
}
}
输出:
{"num":"24","name":"xiaoming"}
{"num":"24","name":"xiaoming"}
执行失败:
package com.zk.jedis;
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class TestJedis {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.flushDB();
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "xiaoming");
jsonObject.put("num", "24");
String result = jsonObject.toJSONString();
// 开启事务
Transaction multi = jedis.multi();
// jedis.watch(result);
try{
multi.set("user1", result);
multi.set("user2", result);
int i = 1 / 0; // 代码执行异常,事务会执行失败
// 执行事务
multi.exec();
}catch (Exception e){
// 失败就放弃事务
multi.discard();
}finally {
// 关闭事务
multi.close();
}
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
}
}
输出:
null
null
SpringBoot 整合 Redis
SpringBoot 操作数据:Spring Data jpa jdbc redis。
Spring Data 也是和 SpringBoot 齐名的项目。
在 SpringBoot 2.x 之后,Jedis 被换成了 Lettuce。
Jedis:底层采用直连的方式,如果多个线程操作,不安全。要避免不安全,就要使用 Jedis Pool 连接池!更像 BIO 模式!
Lettuce:采用 netty,实例可以在多个线程中共享,不存在不安全的情况!可以减少线程数,性能高,更像 NIO 模式!
SpringBoot 所有的配置类,都有一个自动配置类,RedisAutoConfiguration;
自动配置类都会绑定一个 properties 文件,RedisProperties。
RedisTemplate
- 默认的 RedisTemplate 没有过多的设置,redis 保存的对象都是需要序列化的!
- RedisTemplate<Object, Object> 的两个参数都是 Object 类型的,我们使用需要强制转换 RedisTemplate<String, Object>(我们期望使用 String 类型的 key);
- @ConditionalOnMissingBean:判断当前需要注入 Spring 容器的 bean 的实现类是否已经含有,有的话不注入,没有就注入。(可以使用默认的 RedisTemplate,也可以自定义 RedisTemplate)
SpringBoot 整合 Redis 测试
- 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置连接
# SpringBoot 所有的配置类,都有一个自动配置类,RedisAutoConfiguration;
# 自动配置类都会绑定一个 properties 文件,RedisProperties。
# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
- 测试
RedisTemplate 序列化
默认的 RedisTemplate 没有过多的设置,redis 保存的对象都是需要序列化的!
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 我们为了自己使用方便,一般直接使用<String, Object>
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 配置连接工厂
redisTemplate.setConnectionFactory(connectionFactory);
// Json 的序列化
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
//指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringSerializer = new StringRedisSerializer();
// key 采用 String 的序列化方式
redisTemplate.setKeySerializer(stringSerializer);
// Hash 的 key 也采用 String 的序列化方式
redisTemplate.setHashKeySerializer(stringSerializer);
// value 采用 jackson 的序列化方式
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Hash 的 value 也采用 jackson 的序列化方式
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
RedisUtils.setRedisTemplate(redisTemplate);
return redisTemplate;
}
RedisUtils
package com.zte.rdcloud.wbs.util;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
* @author 10307952
* @date 2023/1/31 下午5:05
*/
@Slf4j
@Component
public class RedisUtils {
@Setter
private static RedisTemplate<String, Object> redisTemplate;
/**
* 为键值设置过期时间,单位秒
*
* @param key 键
* @param time 时间(秒)
* @return true:成功;false:失败
*/
public static boolean expire(String key, long time) {
try {
if (time > 0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
}catch (Exception e){
log.error(e.getMessage());
return false;
}
}
//------------------------------String-----------------------------
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public static boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
/**
* 普通缓存放入并设置过期时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public static boolean set(String key, Object value, long time) {
try {
if(time > 0){
redisTemplate.opsForValue().set(key, value, time);
}else{
set(key, value);
}
return true;
}catch (Exception e){
log.error(e.getMessage());
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
public static void del(String... key) {
try {
if(null != key && key.length > 0){
if(key.length == 1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}catch(Exception e){
log.error(e.getMessage());
}
}
/**
* 普通缓存获取
*
* @param key
* @return
*/
public static Object get(String key){
try {
return null == key ? null : redisTemplate.opsForValue().get(key);
}catch(Exception e){
log.error(e.getMessage());
return null;
}
}
/**
* 获取旧值,缓存新值
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public static Object getAndSet(String key, Object value) {
try {
return redisTemplate.opsForValue().getAndSet(key, value);
} catch (Exception e) {
return null;
}
}
//------------------------------Hash-----------------------------
/**
* 向一张hash表中放入数据,如果不存在将创建,存在则覆盖
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public static boolean hSet(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
}catch (Exception e){
log.error(e.getMessage());
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建,存在则覆盖,并设置过期时间
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
/* public static 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){
log.error(e.getMessage());
return false;
}
}*/
/**
* 向一张hash表中放入数据,如果不存在将创建,存在则只设置失效时间(不会设置新值)
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
/* public static boolean hSetIfAbsent(String key, String item, Object value, long time) {
try {
Boolean result = redisTemplate.opsForHash().putIfAbsent(key, item, value);
if (time > 0) {
expire(key, time);
}
return result;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}*/
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
/*public static boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}*/
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以是多个 不能为null
*/
public static void hDel(String key, Object... item) {
try {
redisTemplate.opsForHash().delete(key, item);
}catch(Exception e){
log.error("redis failed hdel", e);
}
}
/**
* 获取指定键对应的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public static Object hGet(String key, String item) {
try {
return redisTemplate.opsForHash().get(key, item);
}catch (Exception e){
log.error(e.getMessage());
return null;
}
}
}