笔记整理自【尚硅谷】Redis 6 入门到精通 超详细 教程
Redis——Jedis操作Redis
即通过 Java 操作 Redis。
1. Jedis基本操作
Ⅰ. 测试连接
连接Redis注意事项
禁用Linux的防火墙:Linux(CentOS7)里执行命令:
systemctl stop/disable firewalld.service
redis.conf
中注释掉bind 127.0.0.1
,然后protected-mode no
-
引入依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.2.0</version> </dependency>
-
测试连接
如果Redis安装在云服务器中,注意配置服务器的防护墙安全组。
public static void main(String[] args) { Jedis jedis = new Jedis("你的redis所在服务器的IP地址", 6379); // 如果你的Redis设置了密码,执行这步 jedis.auth("你的redis密码"); String ping = jedis.ping(); System.out.println(ping); jedis.close(); }
控制台打印:
说明连接成功。
Ⅱ. 操作 Redis
-
Key
@Test public void testKey() { jedis.set("k1", "v1"); jedis.set("k2", "v2"); jedis.set("k3", "v3"); Set<String> keys = jedis.keys("*"); System.out.println(keys.size()); for (String key : keys) { System.out.println(key); } System.out.println(jedis.exists("k1")); System.out.println(jedis.ttl("k1")); System.out.println(jedis.get("k1")); jedis.close(); }
-
String
@Test public void testString() { String set = jedis.set("key1", "v1"); System.out.println(set); String key1 = jedis.get("key1"); System.out.println(key1); // 设置多个key-value jedis.mset("k1", "v1", "k2", "v2"); List<String> mget = jedis.mget("k1", "k2"); System.out.println(mget); jedis.close(); }
-
List
@Test public void testList() { jedis.lpush("list1", "v1", "v2", "v3"); List<String> list = jedis.lrange("list1", 0, -1); list.forEach(System.out::println); jedis.close(); }
-
Set
@Test public void testSet() { Long sadd = jedis.sadd("set1", "tom", "jerry", "jack"); Set<String> set = jedis.smembers("set1"); System.out.println(set); jedis.close(); }
-
Hash
@Test public void testHash() { Map<String, String> map = new HashMap<>(); map.put("id", "1"); map.put("name", "Tom"); map.put("age", "18"); jedis.hset("map1", map); String id = jedis.hget("map1", "id"); String name = jedis.hget("map1", "name"); String age = jedis.hget("map1", "age"); System.out.println("id = " + id); System.out.println("name = " + name); System.out.println("age = " + age); jedis.close(); }
-
zset
@Test public void testZSet() { jedis.zadd("zset1", 100d, "java"); jedis.zadd("zset1", 50d, "c++"); jedis.zadd("zset1", 25d, "php"); Set<String> set = jedis.zrange("zset1", 0, -1); System.out.println(set); jedis.close(); }
2. 模拟验证码案例
完成一个手机验证码功能
业务需求
-
输入手机号,点击发送后随机生成 6 6 6 位数字码, 2 2 2 分钟有效
-
输入验证码,点击验证,返回成功或失败
-
每个手机号每天只能输入 3 3 3 次
需求分析
代码实现
package com.lyc.jedis;
import redis.clients.jedis.Jedis;
import java.util.Random;
public class PhoneCodeTest {
private static Jedis jedis = new Jedis("192.168.232.102", 6379);
private static final int TIMEOUT_CODE = 60 * 2; // 验证码过期时间
private static final int TIMEOUT_PHONE = 60 * 60 * 24; // 一天的时间
public static void main(String[] args) {
// 模拟验证码发送
verifyCode("123123123");
// 验证码校验
//checkVerifyCode("123123123", "057931");
jedis.close();
}
// 随机生成6位数字验证码
public static String getCode() {
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 6; i++) {
sb.append(random.nextInt(10));
}
return sb.toString();
}
// 发送验证码:每个手机每天最多只能发送三次,验证码放到redis中,设置过期时间为120s
public static void verifyCode(String phone) {
// 拼接key
// 手机发送次数key
String countKey = "VerifyCode" + phone + ":count";
// 验证码key
String codeKey = "VerifyCode" + phone + ":code";
// 每个手机每天只能发送三次短信
String count = jedis.get(countKey);
if (count == null) {
// 没有发送次数,第一次发送
// 设置发送次数是1
jedis.setex(countKey, TIMEOUT_PHONE, "1");
} else if (Integer.parseInt(count) < 3) {
// 发送次数+1
jedis.incr(countKey);
} else {
// 发送三次,不能再发送
System.out.println("今天已经发送了3次验证码!");
jedis.close();
return;
}
// 设置验证码 放到redis中 设置过期时间为120s
String code = getCode();
jedis.setex(codeKey, TIMEOUT_CODE, code);
}
// 验证码校验
public static void checkVerifyCode(String phone, String code) {
// 从redis获取验证码
String codeKey = "VerifyCode" + phone + ":code";
String redisCode = jedis.get(codeKey);
if (code.equals(redisCode)) {
System.out.println("验证通过!");
} else {
System.out.println("验证失败!");
}
}
}
测试
-
发送 3 3 3 次验证码
当再发送第 4 4 4 次时会发送失败,关闭redis。
-
验证码校验
-
发送验证码
-
执行校验方法
-
3. SpringBoot整合Redis
-
引入依赖
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- spring2.X集成redis所需common-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.0</version> </dependency> <!-- 还需引入jackson的依赖(redis的配置类会用到) --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.1</version> </dependency>
-
application.properties
配置redis#Redis服务器地址 spring.redis.host=192.168.232.102 #Redis服务器连接端口 spring.redis.port=6379 #Redis数据库索引(默认为0) spring.redis.database= 0 #连接超时时间(毫秒) spring.redis.timeout=1800000 #连接池最大连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-active=20 #最大阻塞等待时间(负数表示没限制) spring.redis.lettuce.pool.max-wait=-1 #连接池中的最大空闲连接 spring.redis.lettuce.pool.max-idle=5 #连接池中的最小空闲连接 spring.redis.lettuce.pool.min-idle=0
-
添加redis配置类
package com.lyc.redis_springboot.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; 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.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; @EnableCaching // 开启缓存(开启redis操作) @Configuration public class RedisConfig extends CachingConfigurerSupport { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setConnectionFactory(factory); // key序列化方式 template.setKeySerializer(redisSerializer); // value序列化 template.setValueSerializer(jackson2JsonRedisSerializer); // value hashmap序列化 template.setHashValueSerializer(jackson2JsonRedisSerializer); return template; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // 解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
-
测试
-
RedisTestController
中添加测试方法package com.lyc.redis_springboot.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/redisTest") public class RedisTestController { @Autowired private RedisTemplate redisTemplate; @GetMapping public String testRedis() { // 设置值到redis redisTemplate.opsForValue().set("name", "lucy"); // 从redis获取值 String name = (String) redisTemplate.opsForValue().get("name"); return name; } }
-
http://localhost:8080/redisTest
-