Spring Boot 操作 Redis 的各种实现
一个 Github 项目搞定微信、QQ、支付宝等第三方登录
注解+反射优雅的实现 Excel 导入导出(通用版)
Fluent Mybatis 牛逼!
Nginx 常用配置清单
这玩意比 ThreadLocal 叼多了,吓得我赶紧分享出来。
一、Jedis,Redisson,Lettuce 三者的区别
共同点:都提供了基于 Redis 操作的 Java API,只是封装程度,具体实现稍有不同。
不同点:
1.1、Jedis
是 Redis 的 Java 实现的客户端。支持基本的数据类型如:String、Hash、List、Set、Sorted Set。
特点:使用阻塞的 I/O,方法调用同步,程序流需要等到 socket 处理完 I/O 才能执行,不支持异步操作。Jedis 客户端实例不是线程安全的,需要通过连接池来使用 Jedis。
1.2、Redisson
优点点:分布式锁,分布式集合,可通过 Redis 支持延迟队列。
1.3、 Lettuce
用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。
基于 Netty 框架的事件驱动的通信层,其方法调用是异步的。Lettuce 的 API 是线程安全的,所以可以操作单个 Lettuce 连接来完成各种操作。
二、RedisTemplate
2.1、使用配置
maven 配置引入,(要加上版本号,我这里是因为 Parent 已声明)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application-dev.yml
spring:
redis:
host:?192.168.1.140
port:?6379
password:
database:?15?#?指定 redis 的分库(共 16 个 0 到 15)
2.2、使用示例
@Resource
private?StringRedisTemplate?stringRedisTemplate;
@Override
public?CustomersEntity?findById(Integer?id)?{
//?需要缓存
//?所有涉及的缓存都需要删除,或者更新
try?{
String?toString?=?stringRedisTemplate.opsForHash().get(REDIS_CUSTOMERS_ONE,?id?+?"").toString();
if?(toString?!=?null)?{
return?JSONUtil.toBean(toString,?CustomersEntity.class);
}
}?catch?(Exception?e)?{
e.printStackTrace();
}
//?缓存为空的时候,先查,然后缓存 redis
Optional<CustomersEntity>?byId?=?customerRepo.findById(id);
if?(byId.isPresent())?{
CustomersEntity?customersEntity?=?byId.get();
try?{
stringRedisTemplate.opsForHash().put(REDIS_CUSTOMERS_ONE,?id?+?"",?JSONUtil.toJsonStr(customersEntity));
}?catch?(Exception?e)?{
e.printStackTrace();
}
return?customersEntity;
}
return?null;
}
2.3、扩展
2.3.1、spring-boot-starter-data-redis 的依赖包
3.3.2、stringRedisTemplate API(部分展示)
opsForHash --> hash 操作
opsForList --> list 操作
opsForSet --> set 操作
opsForValue --> string 操作
opsForZSet --> Zset 操作
3.3.3 StringRedisTemplate 默认序列化机制
public?class?StringRedisTemplate?extends?RedisTemplate<String,?String>?{
/**
*?Constructs?a?new?<code>StringRedisTemplate</code>?instance.?{@link?#setConnectionFactory(RedisConnectionFactory)}
*?and?{@link?#afterPropertiesSet()}?still?need?to?be?called.
*/
public?StringRedisTemplate()?{
RedisSerializer<String>?stringSerializer?=?new?StringRedisSerializer();
setKeySerializer(stringSerializer);
setValueSerializer(stringSerializer);
setHashKeySerializer(stringSerializer);
setHashValueSerializer(stringSerializer);
}
}
三、RedissonClient 操作示例
3.1 基本配置
3.1.1、Maven pom 引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.8.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>LATEST</version>
</dependency>
3.1.2、添加配置文件 Yaml 或者 json 格式
redisson-config.yml
#?Redisson?配置
singleServerConfig:
address:?"redis://192.168.1.140:6379"
password:?null
clientName:?null
database:?15?#选择使用哪个数据库 0~15
idleConnectionTimeout:?10000
pingTimeout:?1000
connectTimeout:?10000
timeout:?3000
retryAttempts:?3
retryInterval:?1500
reconnectionTimeout:?3000
failedAttempts:?3
subscriptionsPerConnection:?5
subscriptionConnectionMinimumIdleSize:?1
subscriptionConnectionPoolSize:?50
connectionMinimumIdleSize:?32
connectionPoolSize:?64
dnsMonitoringInterval:?5000
#dnsMonitoring:?false
threads:?0
nettyThreads:?0
codec:
class:?"org.redisson.codec.JsonJacksonCodec"
transportMode:?"NIO"
或者,配置 redisson-config.json
{
"singleServerConfig":?{
"idleConnectionTimeout":?10000,
"pingTimeout":?1000,
"connectTimeout":?10000,
"timeout":?3000,
"retryAttempts":?3,
"retryInterval":?1500,
"reconnectionTimeout":?3000,
"failedAttempts":?3,
"password":?null,
"subscriptionsPerConnection":?5,
"clientName":?null,
"address":?"redis://192.168.1.140:6379",
"subscriptionConnectionMinimumIdleSize":?1,
"subscriptionConnectionPoolSize":?50,
"connectionMinimumIdleSize":?10,
"connectionPoolSize":?64,
"database":?0,
"dnsMonitoring":?false,
"dnsMonitoringInterval":?5000
},
"threads":?0,
"nettyThreads":?0,
"codec":?null,
"useLinuxNativeEpoll":?false
}
3.1.3、读取配置
新建读取配置类
@Configuration
public?class?RedissonConfig?{
@Bean
public?RedissonClient?redisson()?throws?IOException?{
//?两种读取方式,Config.fromYAML?和?Config.fromJSON
//????????Config?config?=?Config.fromJSON(RedissonConfig.class.getClassLoader().getResource("redisson-config.json"));
Config?config?=?Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml"));
return?Redisson.create(config);
}
}
或者,在 application.yml 中配置如下
spring:
redis:
redisson:
config:?classpath:redisson-config.yaml
3.2 使用示例
@RestController
@RequestMapping("/")
public?class?TeController?{
@Autowired
private?RedissonClient?redissonClient;
static?long?i?=?20;
static?long?sum?=?300;
//????==========================?String?=======================
@GetMapping("/set/{key}")
public?String?s1(@PathVariable?String?key)?{
//?设置字符串
RBucket<String>?keyObj?=?redissonClient.getBucket(key);
keyObj.set(key?+?"1-v1");
return?key;
}
@GetMapping("/get/{key}")
public?String?g1(@PathVariable?String?key)?{
//?设置字符串
RBucket<String>?keyObj?=?redissonClient.getBucket(key);
String?s?=?keyObj.get();
return?s;
}
//????==========================?hash?=======================-=
@GetMapping("/hset/{key}")
public?String?h1(@PathVariable?String?key)?{
Ur?ur?=?new?Ur();
ur.setId(MathUtil.randomLong(1,20));
ur.setName(key);
//?存放?Hash
RMap<String,?Ur>?ss?=?redissonClient.getMap("UR");
ss.put(ur.getId().toString(),?ur);
return?ur.toString();
}
@GetMapping("/hget/{id}")
public?String?h2(@PathVariable?String?id)?{
//?hash?查询
RMap<String,?Ur>?ss?=?redissonClient.getMap("UR");
Ur?ur?=?ss.get(id);
return?ur.toString();
}
//?查询所有的?keys
@GetMapping("/all")
public?String?all(){
RKeys?keys?=?redissonClient.getKeys();
Iterable<String>?keys1?=?keys.getKeys();
keys1.forEach(System.out::println);
return?keys.toString();
}
//?==================?==============读写锁测试?=============================
@GetMapping("/rw/set/{key}")
public?void?rw_set(){
//????????RedissonLock.
RBucket<String>?ls_count?=?redissonClient.getBucket("LS_COUNT");
ls_count.set("300",360000000l,?TimeUnit.SECONDS);
}
//?减法运算
@GetMapping("/jf")
public?void?jf(){
String?key?=?"S_COUNT";
//????????RAtomicLong?atomicLong?=?redissonClient.getAtomicLong(key);
//????????atomicLong.set(sum);
//????????long?l?=?atomicLong.decrementAndGet();
//????????System.out.println(l);
RAtomicLong?atomicLong?=?redissonClient.getAtomicLong(key);
if?(!atomicLong.isExists())?{
atomicLong.set(300l);
}
while?(i?==?0)?{
if?(atomicLong.get()?>?0)?{
long?l?=?atomicLong.getAndDecrement();
try?{
Thread.sleep(1000l);
}?catch?(InterruptedException?e)?{
e.printStackTrace();
}
i?--;
System.out.println(Thread.currentThread().getName()?+?"->"?+?i?+?"->"?+?l);
}
}
}
@GetMapping("/rw/get")
public?String?rw_get(){
String?key?=?"S_COUNT";
Runnable?r?=?new?Runnable()?{
@Override
public?void?run()?{
RAtomicLong?atomicLong?=?redissonClient.getAtomicLong(key);
if?(!atomicLong.isExists())?{
atomicLong.set(300l);
}
if?(atomicLong.get()?>?0)?{
long?l?=?atomicLong.getAndDecrement();
i?--;
System.out.println(Thread.currentThread().getName()?+?"->"?+?i?+?"->"?+?l);
}
}
};
while?(i?!=?0)?{
new?Thread(r).start();
//????????????new?Thread(r).run();
//????????????new?Thread(r).run();
//????????????new?Thread(r).run();
//????????????new?Thread(r).run();
}
RBucket<String>?bucket?=?redissonClient.getBucket(key);
String?s?=?bucket.get();
System.out.println("================线程已结束================================"?+?s);
return?s;
}
}
4.3 扩展
4.3.1 丰富的 jar 支持,尤其是对 Netty NIO 框架
4.3.2 丰富的配置机制选择,这里是详细的配置说明
https://github.com/redisson/redisson/wiki/2.-Configuration
关于序列化机制中,就有很多
![](https://img-blog.csdnimg.cn/img
_convert/c5a0c785ec2cb7597291789e6b1a719c.png)
4.3.3 API 支持(部分展示),具体的 Redis --> RedissonClient ,可查看这里
https://github.com/redisson/redisson/wiki/11.-Redis-commands-mapping
评论