Redis入门(四):springboot整合redis
案例一
- demo为
chnx/springboot/redis01
- 创建springboot项目,导入redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
-
redis依赖中redis自动装配类为我们自动装配了jedis连接工厂和lettuce连接工厂
-
整合jedis,使用jedis操作redis
-
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置yml
spring:
redis: # redis连接的配置
database: 0
host: 127.0.0.1
port: 6379
password: 123456
jedis: # 配置连接池
pool:
max-active: 100
max-idle: 10
max-wait: 100000
timeout: 5000 # 超时时间
- 编写测试方法
@SpringBootTest
class Redis01ApplicationTests {
@Autowired
StringRedisTemplate redisTemplate;
// redisTemplate也可以
// @Autowired
// RedisTemplate redisTemplate;
@Test
void testRedis(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("hello","world");
String hello = operations.get("hello");
System.out.println(hello);
}
}
-
右键运行,测试通过
-
控制层中使用
package com.chnq.redis01.controller;
import com.chnq.redis01.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class JedisController {
@Autowired
RedisTemplate redisTemplate;
@RequestMapping("/str")
public String testStr1(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("username","goudan");
String name = operations.get("username");
System.out.println(name);
return name;
}
@RequestMapping(value = "/str1", method = RequestMethod.POST)
public String listAll(@RequestBody User user){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("name", user.getName());
operations.append("name", user.getAge());
String name = operations.get("name");
System.out.println(name);
return "success";
}
}
案例二
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 如果无法启动可不导入该依赖 -->
<!-- <dependency>-->
<!-- <groupId>org.apache.commons</groupId>-->
<!-- <artifactId>commons-pool2</artifactId>-->
<!-- <version>2.9.0</version>-->
<!-- </dependency>-->
- 配置yml
spring:
redis:
database: 0
host: 192.168.96.192
port: 6379
password: 123456
client-type: lettuce
lettuce:
pool:
max-active: 8
max-wait: -1ms
max-idle: 8
min-idle: 0
timeout: 2000
- 编写LettuceRedisConfig配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;
@Configuration
public class LettuceRedisConfig {
@Bean
public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
- 编写RedisUtils工具类
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils {
@Resource
private RedisTemplate<String, String> redisTemplate;
/**
* 设置key-value
* @param key 键
* @param value 值
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 设置带生存时间的key-value
* @param key 键
* @param value 值
* @param timeout 生存时间
* @param unit 时间单位
*/
public void set(String key, String value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* 设置指定数据的生存时间。
* @param key 键
* @param time 生存时间(秒)
*/
public void expire(String key, long time) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
* 根据key,获取值
* @param key 键
* @return 获取到的值
*/
public String get(String key) {
return String.valueOf(redisTemplate.opsForValue().get(key));
}
/**
* 删除指定信息。
* @param key 键
* @return 是否删除成功
*/
public boolean delete(String key) {
return redisTemplate.delete(key);
}
}
- 测试
@SpringBootTest
public class LettuceTest {
@Resource
private RedisTemplate<String, String> redisTemplate;
@Test
void testRedis(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("hello","world");
String hello = operations.get("hello");
System.out.println(hello);
}
}
- 在需要的地方直接使用工具类的方法
import com.chnq.redis01.entity.User;
import com.chnq.redis01.utils.RedisUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/test1")
public class LettuceController {
// 在需要的类中引用
@Resource
private RedisUtils redisUtils;
@RequestMapping(value = "/str1", method = RequestMethod.POST)
public String listAll(@RequestBody User user){
String name = user.getName();
String age = user.getAge();
redisUtils.set(name, age);
return "success";
}
}
案例三
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
- 测试
package com.atguigu.jedis;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JedisDemo1 {
/**
* 执行main方法会报错
*/
public static void main(String[] args) {
//创建Jedis对象
Jedis jedis = new Jedis("192.168.0.102",6379);
//测试
String value = jedis.ping();
System.out.println(value);
jedis.close();
}
/**
* 操作远程服务器上的redis连接超时
*/
//操作zset
@Test
public void demo5() {
// 创建Jedis对象
Jedis jedis = new Jedis("192.168.0.102",6379);
// 将一个或多个score\member存入key
jedis.zadd("zset01",100d,"shanghai");
jedis.zadd("zset01", 90d, "l4");
jedis.zadd("zset01", 80d, "w5");
jedis.zadd("zset01", 70d, "z6");
// 获取数据后遍历
Set<String> china = jedis.zrange("zset01", 0, 3);
for (String e : china) {
System.out.println(e);
}
// 关闭jedis连接
jedis.close();
}
//操作hash
@Test
public void demo4() {
//创建Jedis对象
Jedis jedis = new Jedis("192.168.0.102",6379);
// 给key集合中的field赋值value,集合中可有多个field-value对
jedis.hset("hash1","userName","lisi");
System.out.println(jedis.hget("hash1","userName"));
// 给key集合赋值多个field-value对
Map<String,String> map = new HashMap<String,String>();
map.put("telphone","13810169999");
map.put("address","atguigu");
map.put("email","abc@163.com");
jedis.hmset("hash2",map);
List<String> result = jedis.hmget("hash2", "telphone","email");
for (String element : result) {
System.out.println(element);
}
jedis.close();
}
//操作set
@Test
public void demo3() {
//创建Jedis对象
Jedis jedis = new Jedis("192.168.0.102",6379);
// 在key集合中添加多个members
jedis.sadd("names","lucy");
jedis.sadd("names","mary");
Set<String> names = jedis.smembers("names");
System.out.println(names);
// 案例二
jedis.sadd("orders", "order02");
jedis.sadd("orders", "order03");
jedis.sadd("orders", "order04");
Set<String> smembers = jedis.smembers("orders");
for (String order : smembers) {
System.out.println(order);
}
// 删除集合中的元素
jedis.srem("orders", "order02");
jedis.close();
}
//操作list
@Test
public void demo2() {
//创建Jedis对象
Jedis jedis = new Jedis("192.168.0.102",6379);
// 向key集合中添加多个值
jedis.lpush("key1","lucy","mary","jack");
List<String> values = jedis.lrange("key1", 0, -1);
System.out.println(values);
jedis.close();
}
//操作key string
@Test
public void demo1() {
//创建Jedis对象
Jedis jedis = new Jedis("192.168.0.102",6379);
//添加
jedis.set("name","lucy");
//获取
String name = jedis.get("name");
System.out.println(name);
//设置多个key-value
jedis.mset("k1","v1","k2","v2");
List<String> mget = jedis.mget("k1", "k2");
System.out.println(mget);
// 获取数据库中所有值
Set<String> keys = jedis.keys("*");
for(String key : keys) {
System.out.println(key);
}
jedis.close();
}
}
案例四
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 使用的是
RedisTemplate
案例一中的方式
案例五
- Lettuce对象常用操作
- 案例为
gitee/ chnx/ springboot / redis_demo01
- 新建一个maven项目,导入依赖
<dependencies>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
</dependencies>
- 编写测试方法
点击查看详情
package com.chen.redisdemo01.lettuce;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisStringAsyncCommands;
import io.lettuce.core.api.reactive.RedisStringReactiveCommands;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
import org.junit.Test;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
public class LettuceDemo {
// 1. 普通方式使用
@Test
public void test1() {
// client
RedisClient client = RedisClient.create("redis://192.168.96.192");
// connection, 线程安全的长连接,连接丢失时会自动重连,直到调用 close 关闭连接。
StatefulRedisConnection<String, String> connection = client.connect();
// sync, 默认超时时间为 60s.
RedisCommands<String, String> redisCommands = connection.sync();
redisCommands.set("name", "老五");
String value = redisCommands.get("name");
System.out.println("姓名:"+value);
// close connection
connection.close();
// shutdown
client.shutdown();
}
// 2. 普通方式使用
@Test
public void test2() {
// client
RedisClient client = RedisClient.create("redis://192.168.96.192");
// connection, 线程安全的长连接,连接丢失时会自动重连,直到调用 close 关闭连接。
StatefulRedisConnection<String, String> connection = client.connect();
// sync, 默认超时时间为 60s.
RedisCommands<String, String> redisCommands = connection.sync();
redisCommands.sadd("k1", "v1");
redisCommands.sadd("k1", "v2");
String value = redisCommands.spop("k1");
int num = Math.toIntExact(redisCommands.scard("k1"));
System.out.println("值:" + value + "+" + "集合个数:" + num);
// close connection
connection.close();
// shutdown
client.shutdown();
}
// 3. 集群方式使用:连接多台redis服务器
@Test
public void test3() {
//创建RedisURI的两种方式
RedisURI redisURI1 = RedisURI.create("redis://192.168.96.192:6379");
RedisURI redisURI2 = RedisURI.Builder.redis("192.168.96.192").withPort(6381).withDatabase(0).build();
List<RedisURI> list = Arrays.asList(redisURI1,redisURI2);
RedisClusterClient client = RedisClusterClient.create(list);
//超时时间
client.setDefaultTimeout(Duration.ofSeconds(20));
StatefulRedisClusterConnection<String, String> connect = client.connect();
/* 同步执行的命令 */
RedisAdvancedClusterCommands<String, String> commands = connect.sync();
commands.set("name1", "老五");
String value = commands.get("name1");
System.out.println("姓名:" + value);
/* 异步执行的命令 */
// RedisAdvancedClusterAsyncCommands<String, String> commands= connect.async();
// RedisFuture<String> future = commands.get("test2");
// try {
// String str = future.get();
// System.out.println(str);
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
connect.close();
client.shutdown();
}
// 异步调用
@Test
public void test4() throws Exception {
// client
RedisClient client = RedisClient.create("redis://192.168.96.192:6379");
StatefulRedisConnection<String, String> connection = client.connect();
// async
RedisStringAsyncCommands<String, String> asyncCommands = connection.async();
asyncCommands.set("name1", "老五");
RedisFuture<String> future = asyncCommands.get("name1");
future.thenAccept((str) -> {
System.out.println("姓名:" + str);
});
System.out.println("END");
Thread.sleep(10*1000);
connection.close();
client.shutdown();
}
// reactive方式调用
@Test
public void test5() throws Exception {
// client
RedisClient client = RedisClient.create("redis://192.168.96.192:6379");
// connect
StatefulRedisConnection<String, String> connection = client.connect();
// reactive
RedisStringReactiveCommands<String, String> reactiveCommands = connection.reactive();
reactiveCommands.set("name", "老五");
reactiveCommands.get("name").subscribe((str) -> {
System.out.println("name:" + str);
});
System.out.println("END");
Thread.sleep(10 * 1000);
connection.close();
client.shutdown();
}
}
案例六
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- springboot整合redis依赖,使用lettuce操作redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.commons</groupId>-->
<!-- <artifactId>commons-pool2</artifactId>-->
<!-- <version>2.9.0</version>-->
<!-- </dependency>-->
</dependencies>
- 配置yml
server:
port: 8080
spring:
redis:
database: 0
host: 192.168.96.192
password: 123456
client-type: lettuce
lettuce:
pool:
max-idle: 8
min-idle: 0
max-active: 8
max-wait: -1
timeout: 30000
- 编写配置类
package com.chnq.redis01.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
- 编写工具类
点击查看详情
package com.chnq.redis01.utils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Component
public final class RedisUtils {
@Autowired
private RedisTemplate<String, Object> 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 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
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 值
* @param time 时间(秒)
* @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 值
* @param time 时间(秒)
* @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;
}
}
}
- 编写测试类测试
import com.chnq.redis01.utils.RedisUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import javax.annotation.Resource;
@SpringBootTest
public class LettuceTest {
@Resource
private RedisTemplate<String, String> redisTemplate;
@Test
void testRedis(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("hello1","world");
String hello = operations.get("hello1");
System.out.println(hello);
}
}
- 编写实体类
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private String age;
}
- 在controller层测试
import com.chnq.redis01.entity.User;
import com.chnq.redis01.utils.RedisUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/test")
public class TestController {
// 在需要的类中引用
@Resource
private RedisUtils redisUtils;
@RequestMapping(value = "/str1", method = RequestMethod.POST)
public String listAll(@RequestBody User user){
String name = user.getName();
String age = user.getAge();
redisUtils.set(name, age);
return "success";
}
}
案例七
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @Description: 自定义 RedisTemplate + 配置缓存管理器(作用于注解缓存)
* 注意!自定义序列化后必须配置java8时间类型的序列化否则会报错; 也可以使用以下两个注解在对应字段上替代
* @JsonDeserialize(using = LocalDateTimeDeserializer.class)
* @JsonSerialize(using = LocalDateTimeSerializer.class)
*/
@EnableCaching
@Configuration
public class RedisConfig {
// 缓存过期时间(秒)
private static final Long EXPIRE_TIME = 60L;
/**
* 自定义Key为String类型Value为Object类型的Redis操作模板
* 注意SpringDataRedis本身提供了: StringRedisTemplate, RedisTemplate<Object,Object> 两个不同类型的操作模板
*/
@Bean(name = "stringByObjectTemplate")
public RedisTemplate<String, Object> stringByObjectTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//使用Jackson2JsonRedisSerializer进行序列化
Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
// 序列化 java8时间类型
JavaTimeModule timeModule = new JavaTimeModule();
timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
objectMapper.registerModule(timeModule);
jsonRedisSerializer.setObjectMapper(objectMapper);
//自定义String序列化配置
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key使用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key也是用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value的key使用jackson的序列化方式
template.setValueSerializer(jsonRedisSerializer);
//hash的value也是用jackson的序列化方式
template.setHashValueSerializer(jsonRedisSerializer);
//配置完之后将所有的properties设置进去
template.afterPropertiesSet();
return template;
}
/**
* cacheManager 缓存管理器, 有关缓存的配置都在这里进行配置
* 修改注解缓存序列化方式, 不使用JDK默认的序列化方式, 并配置java8序列化和反序列化配置
* 参考: https://www.cnblogs.com/yanlong300/p/11905978.html
* 核心类:
* GenericJackson2JsonRedisSerializer
* Jackson2JsonRedisSerializer
* ObjectMapper
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 配置序列化java8时间类型
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule());
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
// 配置自定义序列化方式和失效时间
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer))
.entryTtl(Duration.ofSeconds(EXPIRE_TIME));
return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build();
}
}
案例八
- 参考为
bili_shiro_redis
使用redis作为缓存数据库存储权限信息
,核心代码如下
package com.baizhi.springboot_jsp_shiro.shiro.cache;
import com.baizhi.springboot_jsp_shiro.utils.ApplicationContextUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.Collection;
import java.util.Set;
//自定义redis缓存的实现
public class RedisCache<k,v> implements Cache<k,v> {
private String cacheName;
public RedisCache() {
}
public RedisCache(String cacheName) {
this.cacheName = cacheName;
}
@Override
public v get(k k) throws CacheException {
System.out.println("get key:"+k);
return (v) getRedisTemplate().opsForHash().get(this.cacheName,k.toString());
}
@Override
public v put(k k, v v) throws CacheException {
System.out.println("put key: "+k);
System.out.println("put value:"+v);
getRedisTemplate().opsForHash().put(this.cacheName,k.toString(),v);
return null;
}
@Override
public v remove(k k) throws CacheException {
System.out.println("=============remove=============");
return (v) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());
}
@Override
public void clear() throws CacheException {
System.out.println("=============clear==============");
getRedisTemplate().delete(this.cacheName);
}
@Override
public int size() {
return getRedisTemplate().opsForHash().size(this.cacheName).intValue();
}
@Override
public Set<k> keys() {
return getRedisTemplate().opsForHash().keys(this.cacheName);
}
@Override
public Collection<v> values() {
return getRedisTemplate().opsForHash().values(this.cacheName);
}
private RedisTemplate getRedisTemplate(){
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
案例总结
- 案例3创建maven工程,使用jedis直接操作redis
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
- 案例5创建maven工程,使用lettuce直接操作redis
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
- 案例1创建spring boot项目,使用jedis连接redis,使用redisTemplate操作redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 案例2创建spring boot项目,使用lettuce连接redis,编写RedisUtils操作redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 案例6新建spring boot项目,使用lettuce连接redis,编写RedisUtils操作redis,
redis工具类更加全面
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>