Redis(四):后端开发使用redis
2021-12-07 16:12
651 查看
案例一
- 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>
相关文章推荐
- 后端(Java)开发人员使用Redis时的注意事项
- 游戏开发中redis的使用
- 全新安装Mac OSX 开发者环境 同时使用homebrew搭建 PHP,Nginx ,MySQL,Redis,Memcache ... ... (LNMP开发环境)
- Jedis (Redis 官方首选的 Java 客户端开发包 )的使用
- Redis 的 C++开发包 使用例子
- Golang web 开发实战之 session 缓存:如何使用 redigo 将一个结构体数据保存到 redis?
- 全新安装Mac OSX 开发者环境 同时使用homebrew搭建 PHP,Nginx ,MySQL,Redis,Memcache ... ... (LNMP开发环境)
- 使用spring+jedis-2.5.2.jar开发redis应用
- Redis中modules扩展模块的开发使用详解
- 使用Mock.js进行独立于后端的前端开发
- ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用
- Tomcat与Servelet的原理与使用(Java后端开发)
- 全新安装Mac OSX 开发者环境 同时使用homebrew搭建 PHP,Nginx ,MySQL,Redis,Memcache ... ... (LNMP开发环境)
- 【Redis】redis的安装、配置运行及Jedis客户端的开发使用
- 使用spring-data-redis开发redis应用
- redis(一)在互联网开发中的使用之简单介绍
- jedis使用api(java redis开发指南)
- Magento2开发教程 - Session 存储中使用Redis
- 在项目开发中使用Redis作缓存
- 如何在Vue项目中使用Mockjs,模拟接口返回的数据,实现前后端分离独立开发