From be99853779661dfaf8899369a561ba8740e137f8 Mon Sep 17 00:00:00 2001 From: YuNan <3194726156@qq.com> Date: Sat, 9 Nov 2024 16:49:13 +0800 Subject: [PATCH] =?UTF-8?q?redis=E7=9B=B8=E5=BA=94=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yunan/YuNanDemoApplication.java | 5 + .../java/com/yunan/config/RedisConfig.java | 141 +- .../com/yunan/controller/AuthController.java | 16 +- .../yunan/controller/CaptchaController.java | 6 +- .../com/yunan/dto/{User.java => Users.java} | 32 +- .../java/com/yunan/mapper/AuthMapper.java | 4 +- .../yunan/response/{R.java => Result.java} | 22 +- .../java/com/yunan/service/AuthService.java | 2 +- .../java/com/yunan/service/EmailService.java | 3 +- .../com/yunan/service/RedisExpireTask.java | 43 + .../yunan/service/impl/AuthServiceImpl.java | 23 +- .../yunan/service/impl/EmailServiceImpl.java | 30 +- .../main/java/com/yunan/util/RedisUtils.java | 1697 ++++++++++++----- .../src/main/resources/application.yml | 7 +- .../src/main/resources/mapper/AuthMapper.xml | 11 + 15 files changed, 1506 insertions(+), 536 deletions(-) rename YuNan-system-start/src/main/java/com/yunan/dto/{User.java => Users.java} (66%) rename YuNan-system-start/src/main/java/com/yunan/response/{R.java => Result.java} (67%) create mode 100644 YuNan-system-start/src/main/java/com/yunan/service/RedisExpireTask.java create mode 100644 YuNan-system-start/src/main/resources/mapper/AuthMapper.xml diff --git a/YuNan-system-start/src/main/java/com/yunan/YuNanDemoApplication.java b/YuNan-system-start/src/main/java/com/yunan/YuNanDemoApplication.java index 5715769..e2e767e 100644 --- a/YuNan-system-start/src/main/java/com/yunan/YuNanDemoApplication.java +++ b/YuNan-system-start/src/main/java/com/yunan/YuNanDemoApplication.java @@ -3,12 +3,17 @@ package com.yunan; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; import java.net.InetAddress; import java.net.UnknownHostException; @Slf4j @SpringBootApplication(scanBasePackages = "com.yunan") +@EnableCaching//开启缓存 +@EnableScheduling // 启用定时任务 public class YuNanDemoApplication { public static void main(String[] args) { diff --git a/YuNan-system-start/src/main/java/com/yunan/config/RedisConfig.java b/YuNan-system-start/src/main/java/com/yunan/config/RedisConfig.java index 5cc3c82..5ef5222 100644 --- a/YuNan-system-start/src/main/java/com/yunan/config/RedisConfig.java +++ b/YuNan-system-start/src/main/java/com/yunan/config/RedisConfig.java @@ -1,30 +1,147 @@ package com.yunan.config; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +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.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; +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; + /*告诉spring,运行的时候加载读取这个类*/ @Slf4j @Configuration public class RedisConfig { - @Bean - public RedisTemplate - redisTemplate(RedisConnectionFactory connectionFactory) { - RedisTemplate redisTemplate = new - RedisTemplate(); - redisTemplate.setKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer - (new JdkSerializationRedisSerializer()); - redisTemplate.setConnectionFactory(connectionFactory); - log.info("redis配置已加载!!!"); - return redisTemplate; + @SuppressWarnings("all") + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + //为了使开发方便,直接使用 + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + //Json序列化配置 + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(objectMapper); + //string的序列化 + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + //key采用string的序列化方式 + template.setKeySerializer(stringRedisSerializer); + //hash的key也是用string的序列化方式 + template.setHashKeySerializer(stringRedisSerializer); + //value序列化方式采用jackson + template.setValueSerializer(jackson2JsonRedisSerializer); + //hash的value序列化方式采用jackson + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.afterPropertiesSet(); + // 输出 Redis 配置信息 + log.info("Redis配置已加载!!!"); + // 检查 Redis 客户端类型并获取配置 + if (factory instanceof LettuceConnectionFactory) { + LettuceConnectionFactory lettuceConnectionFactory = (LettuceConnectionFactory) factory; + String redisHost = lettuceConnectionFactory.getHostName(); + int redisPort = lettuceConnectionFactory.getPort(); +// log.info("Redis 连接地址: \t http://"+ redisHost + ":" + redisPort); + log.info("Redis 连接地址: {}:{}", redisHost , redisPort); + } else if (factory instanceof RedisStandaloneConfiguration) { + RedisStandaloneConfiguration config = (RedisStandaloneConfiguration) factory; + String redisHost = config.getHostName(); + int redisPort = config.getPort(); + log.info("Redis 连接地址: \t http://"+ redisHost +":"+ redisPort); + } + + return template; } + + /** + * 实例化具体的缓存配置! + * 设置缓存方式JSON + * 设置缓存时间 单位秒 + * @param ttl + * @return + */ + private RedisCacheConfiguration redisCacheConfiguration(Long ttl){ + //设置jackson序列化工具 + Jackson2JsonRedisSerializer objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); + //常见jackson的对象映射器,并设置一些基本属性 + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.configure(MapperFeature.USE_ANNOTATIONS,false); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + objectMapper.activateDefaultTyping( + LaissezFaireSubTypeValidator.instance, + ObjectMapper.DefaultTyping.NON_FINAL, + JsonTypeInfo.As.PROPERTY); + objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper); + return RedisCacheConfiguration.defaultCacheConfig() + .entryTtl(Duration.ofSeconds(ttl))//设置缓存时间 + .disableCachingNullValues() + .serializeKeysWith(keyPair()) + .serializeValuesWith(valuePair()); + } + //配置缓存管理器 + @Bean("cacheManagerHour") + @Primary //同类型,多个bean,默认生效! 默认缓存时间1小时! 可以选择! + public CacheManager cacheManagerHour(RedisConnectionFactory factory){ + //缓存时间一小时 + RedisCacheConfiguration redisCacheConfiguration = redisCacheConfiguration( 3600L); + //构建缓存对象 + return RedisCacheManager.builder(factory) + .cacheDefaults(redisCacheConfiguration) + .transactionAware() + .build(); + } + + //缓存一天的配置 + @Bean(name ="cacheManagerDay") + public RedisCacheManager cacheManagerDay(RedisConnectionFactory factory){ + //缓存时间为一天 + RedisCacheConfiguration redisCacheConfiguration = redisCacheConfiguration(24 * 3600L); + return RedisCacheManager.builder(factory) + .cacheDefaults(redisCacheConfiguration) + .transactionAware() + .build(); + } + + /** + * 配置键序列化 + * @return String序列化 + */ + @Bean + RedisSerializationContext.SerializationPair keyPair(){ + return RedisSerializationContext.SerializationPair.fromSerializer( new StringRedisSerializer()); + } + + /** + * 配置值序列化 + * @return GenericJackson2JsonRedisSerializer序列化Object + */ + @Bean + RedisSerializationContext.SerializationPair valuePair(){ + return RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()); + } + } diff --git a/YuNan-system-start/src/main/java/com/yunan/controller/AuthController.java b/YuNan-system-start/src/main/java/com/yunan/controller/AuthController.java index e03ec6b..faa04db 100644 --- a/YuNan-system-start/src/main/java/com/yunan/controller/AuthController.java +++ b/YuNan-system-start/src/main/java/com/yunan/controller/AuthController.java @@ -53,9 +53,7 @@ public class AuthController { @PostMapping("/register") @ApiOperation("用户注册") public ResponseEntity register(@RequestBody @Valid RegisterDTO registerDTO) throws MessagingException, UnsupportedEncodingException { - //获取发送的验证码 - String rightCode = emailCodeMap.get(registerDTO.getEmail()); - return authService.register(registerDTO, rightCode); + return authService.register(registerDTO); } // 存储已发送的验证码 @@ -70,19 +68,9 @@ public class AuthController { @PostMapping("/sendEmail") @ApiOperation("邮箱验证码") public ApiResponse sendEmail(@RequestBody @Valid RegisterDTO registerDTO) throws MessagingException { - // 生成验证码 - String code = VerificationCodeUtils.generateCode(6); - // 发送邮件 - String subject = "注册验证码"; - String content = "尊敬的用户,您的验证码为:" + code; + return emailService.sendMail(registerDTO.getEmail()); - emailService.sendMail(registerDTO.getEmail(), subject, content); - - // 保存验证码 - emailCodeMap.put(registerDTO.getEmail(), code); - - return new ApiResponse<>(ResponseCode.SUCCESS,"验证码已发送"); } diff --git a/YuNan-system-start/src/main/java/com/yunan/controller/CaptchaController.java b/YuNan-system-start/src/main/java/com/yunan/controller/CaptchaController.java index aa340ee..fc8aaf2 100644 --- a/YuNan-system-start/src/main/java/com/yunan/controller/CaptchaController.java +++ b/YuNan-system-start/src/main/java/com/yunan/controller/CaptchaController.java @@ -1,7 +1,7 @@ package com.yunan.controller; import com.yunan.dto.Captcha; -import com.yunan.response.R; +import com.yunan.response.Result; import com.yunan.service.CaptchaService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -24,8 +24,8 @@ public class CaptchaController { @ApiOperation(value = "生成验证码拼图") @PostMapping("get-captcha") - public R getCaptcha(@RequestBody Captcha captcha) { - return R.ok(captchaService.getCaptcha(captcha)); + public Result getCaptcha(@RequestBody Captcha captcha) { + return Result.ok(captchaService.getCaptcha(captcha)); } } diff --git a/YuNan-system-start/src/main/java/com/yunan/dto/User.java b/YuNan-system-start/src/main/java/com/yunan/dto/Users.java similarity index 66% rename from YuNan-system-start/src/main/java/com/yunan/dto/User.java rename to YuNan-system-start/src/main/java/com/yunan/dto/Users.java index 9e96c04..962b9f5 100644 --- a/YuNan-system-start/src/main/java/com/yunan/dto/User.java +++ b/YuNan-system-start/src/main/java/com/yunan/dto/Users.java @@ -5,7 +5,7 @@ import java.io.Serializable; /** * 用户实体类 */ -public class User implements Serializable { +public class Users implements Serializable { private Integer id; /** 用户名*/ private String username; @@ -14,20 +14,20 @@ public class User implements Serializable { /** 邮箱*/ private String email; /** 创建用户信息时间 */ - private String createTime; + private String createdTime; /** 修改用户信息时间 */ - private String updateTime; + private String updatedTime; /** 用户状态*/ private int state; @Override public String toString() { - return "User{" + + return "Users{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + - ", createTime='" + createTime + '\'' + - ", updateTime='" + updateTime + '\'' + + ", createTime='" + createdTime + '\'' + + ", updateTime='" + updatedTime + '\'' + ", state=" + state + '}'; } @@ -56,11 +56,11 @@ public class User implements Serializable { this.password = password; } - public String getEmai() { + public String getEmail() { return email; } - public void setEmai(String email) { + public void setEmail(String email) { this.email = email; } @@ -72,19 +72,19 @@ public class User implements Serializable { this.state = state; } - public String getCreate_Time() { - return createTime; + public String getCreated_Time() { + return createdTime; } - public void setCreate_Time(String create_Time) { - this.createTime = create_Time; + public void setCreated_Time(String create_Time) { + this.createdTime = create_Time; } - public String getUpdate_Time() { - return updateTime; + public String getUpdated_Time() { + return updatedTime; } - public void setUpdate_Time(String update_Time) { - this.updateTime = update_Time; + public void setUpdated_Time(String update_Time) { + this.updatedTime = update_Time; } } diff --git a/YuNan-system-start/src/main/java/com/yunan/mapper/AuthMapper.java b/YuNan-system-start/src/main/java/com/yunan/mapper/AuthMapper.java index eecf0b7..642b87b 100644 --- a/YuNan-system-start/src/main/java/com/yunan/mapper/AuthMapper.java +++ b/YuNan-system-start/src/main/java/com/yunan/mapper/AuthMapper.java @@ -1,10 +1,10 @@ package com.yunan.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.yunan.dto.User; +import com.yunan.dto.Users; import org.apache.ibatis.annotations.Mapper; @Mapper -public interface AuthMapper extends BaseMapper { +public interface AuthMapper extends BaseMapper { } diff --git a/YuNan-system-start/src/main/java/com/yunan/response/R.java b/YuNan-system-start/src/main/java/com/yunan/response/Result.java similarity index 67% rename from YuNan-system-start/src/main/java/com/yunan/response/R.java rename to YuNan-system-start/src/main/java/com/yunan/response/Result.java index 765b6b5..b1ff6ad 100644 --- a/YuNan-system-start/src/main/java/com/yunan/response/R.java +++ b/YuNan-system-start/src/main/java/com/yunan/response/Result.java @@ -1,35 +1,34 @@ package com.yunan.response; -public class R { - +public class Result { private int code; // 状态码,200代表成功,其他代表失败 private String message; // 响应信息 private Object data; // 响应数据 // 默认构造函数 - public R() { + public Result() { } // 构造函数 - public R(int code, String message, Object data) { + public Result(int code, String message, Object data) { this.code = code; this.message = message; this.data = data; } // 成功返回 - public static R ok(Object data) { - return new R(200, "成功", data); // 200代表成功 + public static Result ok(Object data) { + return new Result(200, "成功", data); // 200代表成功 } // 错误返回 - public static R error(String message) { - return new R(500, message, null); // 500代表服务器错误,message为错误信息 + public static Result error(String message) { + return new Result(500, message, null); // 500代表服务器错误,message为错误信息 } // 错误返回,带code和message - public static R error(int code, String message) { - return new R(code, message, null); // 根据传入的code返回不同的错误 + public static Result error(int code, String message) { + return new Result(code, message, null); // 根据传入的code返回不同的错误 } // get 和 set 方法 @@ -60,11 +59,10 @@ public class R { // 重写toString方法,方便调试输出 @Override public String toString() { - return "R{" + + return "Result{" + "code=" + code + ", message='" + message + '\'' + ", data=" + data + '}'; } } - diff --git a/YuNan-system-start/src/main/java/com/yunan/service/AuthService.java b/YuNan-system-start/src/main/java/com/yunan/service/AuthService.java index 9f9b6b9..8448ad7 100644 --- a/YuNan-system-start/src/main/java/com/yunan/service/AuthService.java +++ b/YuNan-system-start/src/main/java/com/yunan/service/AuthService.java @@ -10,5 +10,5 @@ import java.io.UnsupportedEncodingException; public interface AuthService { - ResponseEntity register(RegisterDTO registerDTO, String rightCode) throws UnsupportedEncodingException, AddressException, MessagingException; + ResponseEntity register(RegisterDTO registerDTO) throws UnsupportedEncodingException, AddressException, MessagingException; } diff --git a/YuNan-system-start/src/main/java/com/yunan/service/EmailService.java b/YuNan-system-start/src/main/java/com/yunan/service/EmailService.java index 1d30800..227baf2 100644 --- a/YuNan-system-start/src/main/java/com/yunan/service/EmailService.java +++ b/YuNan-system-start/src/main/java/com/yunan/service/EmailService.java @@ -1,6 +1,7 @@ package com.yunan.service; +import com.yunan.response.ApiResponse; import org.springframework.stereotype.Service; import javax.mail.MessagingException; @@ -8,7 +9,7 @@ import javax.mail.MessagingException; @Service public interface EmailService { - void sendMail(String email, String subject, String content) throws MessagingException; + ApiResponse sendMail(String email) throws MessagingException; } diff --git a/YuNan-system-start/src/main/java/com/yunan/service/RedisExpireTask.java b/YuNan-system-start/src/main/java/com/yunan/service/RedisExpireTask.java new file mode 100644 index 0000000..d1f1be2 --- /dev/null +++ b/YuNan-system-start/src/main/java/com/yunan/service/RedisExpireTask.java @@ -0,0 +1,43 @@ +package com.yunan.service; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class RedisExpireTask { + private final long time = 300000; //五分钟 + + private RedisTemplate redisTemplate; + + public RedisExpireTask(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + // 每隔一分钟执行一次 + @Scheduled(fixedRate = time) + public void removeExpiredKeys() { + long now = System.currentTimeMillis(); + // 获取过期的 hashKey + Set expiredHashKeys = redisTemplate.opsForZSet().rangeByScore("rightCode:expire", 0, now); + + if (expiredHashKeys != null && !expiredHashKeys.isEmpty()) { + // 将 Set 转换为 Set + Set expiredHashKeysSet = expiredHashKeys.stream() + .map(Object::toString) // 将 Object 转换为 String + .collect(Collectors.toSet()); + + // 删除过期的数据 + redisTemplate.opsForZSet().remove("rightCode:expire", expiredHashKeysSet.toArray(new String[0])); + + // 同时从哈希表中删除对应的 hashKey + for (String hashKey : expiredHashKeysSet) { + redisTemplate.opsForHash().delete("rightCode", hashKey); + } + } + } +} + diff --git a/YuNan-system-start/src/main/java/com/yunan/service/impl/AuthServiceImpl.java b/YuNan-system-start/src/main/java/com/yunan/service/impl/AuthServiceImpl.java index eef98fd..c39cfc7 100644 --- a/YuNan-system-start/src/main/java/com/yunan/service/impl/AuthServiceImpl.java +++ b/YuNan-system-start/src/main/java/com/yunan/service/impl/AuthServiceImpl.java @@ -2,10 +2,12 @@ package com.yunan.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.yunan.dto.RegisterDTO; +import com.yunan.dto.Users; import com.yunan.mapper.AuthMapper; -import com.yunan.dto.User; import com.yunan.response.ErrorResponse; import com.yunan.service.AuthService; +import com.yunan.util.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -18,25 +20,30 @@ import javax.annotation.Resource; public class AuthServiceImpl implements AuthService { @Resource private AuthMapper authMapper; + @Autowired + RedisUtils redisUtils; @Override - public ResponseEntity register(RegisterDTO registerDTO, String rightCode) { + public ResponseEntity register(RegisterDTO registerDTO) { + //获取正确的验证码 + Object rightCode = redisUtils.hGet("rightCode", registerDTO.getEmail()); //处理registerDTO对数据为空的逻辑 // 验证验证码的正确性 - if(registerDTO.getCode() == rightCode){ - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(User::getUsername, registerDTO.getUsername()); + if(registerDTO.getCode().equals(rightCode)){ + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Users::getEmail, registerDTO.getEmail()); if(authMapper.selectOne(queryWrapper) != null) { return ResponseEntity .status(HttpStatus.CONFLICT) .body(new ErrorResponse("用户名已存在!!!")); } - User user = new User(); + Users user = new Users(); user.setUsername(registerDTO.getUsername()); user.setPassword(registerDTO.getPassword()); - user.setEmai(registerDTO.getEmail()); - boolean isSaved = authMapper.insert(user) > 0; + user.setEmail(registerDTO.getEmail()); +// boolean isSaved = authMapper.insert(user) > 0; + boolean isSaved = true; if (isSaved) { return ResponseEntity .status(HttpStatus.OK) diff --git a/YuNan-system-start/src/main/java/com/yunan/service/impl/EmailServiceImpl.java b/YuNan-system-start/src/main/java/com/yunan/service/impl/EmailServiceImpl.java index 52fddf2..00c36b0 100644 --- a/YuNan-system-start/src/main/java/com/yunan/service/impl/EmailServiceImpl.java +++ b/YuNan-system-start/src/main/java/com/yunan/service/impl/EmailServiceImpl.java @@ -1,6 +1,10 @@ package com.yunan.service.impl; +import com.yunan.constant.ResponseCode; +import com.yunan.response.ApiResponse; import com.yunan.service.EmailService; +import com.yunan.util.RedisUtils; +import com.yunan.util.VerificationCodeUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; @@ -9,6 +13,7 @@ import org.springframework.stereotype.Service; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import java.util.concurrent.TimeUnit; @Service public class EmailServiceImpl implements EmailService { @@ -17,24 +22,31 @@ public class EmailServiceImpl implements EmailService { @Value("${spring.mail.username}") private String from; + @Autowired + RedisUtils redisUtils; + + + public ApiResponse sendMail(String email) throws MessagingException { + + // 生成验证码 + String code = VerificationCodeUtils.generateCode(6); + + // 发送邮件 + String subject = "注册验证码"; + String content = "尊敬的用户,您的验证码为:" + code + ",有效期5分钟,请勿泄漏!"; - /** - * 发送邮件 - * - * @param to 收件人邮箱 - * @param subject 邮件主题 - * @param content 邮件内容 - */ - public void sendMail(String to, String subject, String content) throws MessagingException { // 创建邮件消息 MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); - helper.setTo(to); + helper.setTo(email); helper.setSubject(subject); helper.setText(content, true); // 发送邮件 mailSender.send(message); + + redisUtils.hPutWithExpire("rightCode", email, code, 5, TimeUnit.SECONDS); + return new ApiResponse<>(ResponseCode.SUCCESS, "验证码已发送"); } } \ No newline at end of file diff --git a/YuNan-system-start/src/main/java/com/yunan/util/RedisUtils.java b/YuNan-system-start/src/main/java/com/yunan/util/RedisUtils.java index d05b036..c19832a 100644 --- a/YuNan-system-start/src/main/java/com/yunan/util/RedisUtils.java +++ b/YuNan-system-start/src/main/java/com/yunan/util/RedisUtils.java @@ -1,11 +1,11 @@ package com.yunan.util; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.connection.DataType; +import org.springframework.data.redis.core.*; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; +import javax.annotation.Resource; +import java.sql.Date; import java.util.Collection; import java.util.List; import java.util.Map; @@ -13,559 +13,1344 @@ import java.util.Set; import java.util.concurrent.TimeUnit; /** - * redis 工具类 - * - * @author simon - * @date 2018-11-28 10:35 - **/ + * redis工具类 + * @author NanYu + * @date 2024/11/09 + */ @Component public class RedisUtils { - /** - * 注入redisTemplate bean - */ - @Autowired - private RedisTemplate redisTemplate; + @Resource + private RedisTemplate redisTemplate; + + public void setRedisTemplate(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + public RedisTemplate getRedisTemplate() { + return this.redisTemplate; + } + + /** -------------------key相关操作--------------------- */ /** - * 指定缓存失效时间 + * 删除key * - * @param key 键 - * @param time 时间(秒) + * @param key + */ + public void delete(String key) { + redisTemplate.delete(key); + } + + /** + * 批量删除key + * + * @param keys + */ + public void delete(Collection keys) { + redisTemplate.delete(keys); + } + + /** + * 序列化key + * + * @param key * @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; - } + public byte[] dump(String key) { + return redisTemplate.dump(key); } /** - * 根据key获取过期时间 + * 是否存在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) 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) + * @param key * @return */ - public long incr(String key, long delta) { - if (delta < 0) { - throw new RuntimeException("递增因子必须大于0"); - } - return redisTemplate.opsForValue().increment(key, delta); + public Boolean hasKey(String key) { + return redisTemplate.hasKey(key); } /** - * 递减 + * 设置过期时间 * - * @param key 键 - * @param delta 要减少几(小于0) + * @param key + * @param timeout + * @param unit * @return */ - public long decr(String key, long delta) { - if (delta < 0) { - throw new RuntimeException("递减因子必须大于0"); - } - return redisTemplate.opsForValue().increment(key, -delta); - } - // ================================Hash(哈希)================================= - - /** - * HashGet - * - * @param key 键 不能为null - * @param item 项 不能为null - * @return 值 - */ - public Object hget(String key, String item) { - return redisTemplate.opsForHash().get(key, item); + public Boolean expire(String key, long timeout, TimeUnit unit) { + return redisTemplate.expire(key, timeout, unit); } /** - * 获取hashKey对应的所有键值 + * 设置过期时间 * - * @param key 键 - * @return 对应的多个键值 + * @param key + * @param date + * @return */ - public Map hmget(String key) { + public Boolean expireAt(String key, Date date) { + return redisTemplate.expireAt(key, date); + } + + /** + * 查找匹配的key + * + * @param pattern + * @return + */ + public Set keys(String pattern) { + return redisTemplate.keys(pattern); + } + + /** + * 将当前数据库的 key 移动到给定的数据库 db 当中 + * + * @param key + * @param dbIndex + * @return + */ + public Boolean move(String key, int dbIndex) { + return redisTemplate.move(key, dbIndex); + } + + /** + * 移除 key 的过期时间,key 将持久保持 + * + * @param key + * @return + */ + public Boolean persist(String key) { + return redisTemplate.persist(key); + } + + /** + * 返回 key 的剩余的过期时间 + * + * @param key + * @param unit + * @return + */ + public Long getExpire(String key, TimeUnit unit) { + return redisTemplate.getExpire(key, unit); + } + + /** + * 返回 key 的剩余的过期时间 + * + * @param key + * @return + */ + public Long getExpire(String key) { + return redisTemplate.getExpire(key); + } + + /** + * 从当前数据库中随机返回一个 key + * + * @return + */ + public String randomKey() { + return (String) redisTemplate.randomKey(); + } + + /** + * 修改 key 的名称 + * + * @param oldKey + * @param newKey + */ + public void rename(String oldKey, String newKey) { + redisTemplate.rename(oldKey, newKey); + } + + /** + * 仅当 newkey 不存在时,将 oldKey 改名为 newkey + * + * @param oldKey + * @param newKey + * @return + */ + public Boolean renameIfAbsent(String oldKey, String newKey) { + return redisTemplate.renameIfAbsent(oldKey, newKey); + } + + /** + * 返回 key 所储存的值的类型 + * + * @param key + * @return + */ + public DataType type(String key) { + return redisTemplate.type(key); + } + + /** -------------------string相关操作--------------------- */ + + /** + * 设置指定 key 的值 + * + * @param key + * @param value + */ + public void set(String key, String value) { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 获取指定 key 的值 + * + * @param key + * @return + */ + public String get(String key) { + return (String) redisTemplate.opsForValue().get(key); + } + + /** + * 返回 key 中字符串值的子字符 + * + * @param key + * @param start + * @param end + * @return + */ + public String getRange(String key, long start, long end) { + return redisTemplate.opsForValue().get(key, start, end); + } + + /** + * 将给定 key 的值设为 value ,并返回 key 的旧值(old value) + * + * @param key + * @param value + * @return + */ + public String getAndSet(String key, String value) { + return (String) redisTemplate.opsForValue().getAndSet(key, value); + } + + /** + * 对 key 所储存的字符串值,获取指定偏移量上的位(bit) + * + * @param key + * @param offset + * @return + */ + public Boolean getBit(String key, long offset) { + return redisTemplate.opsForValue().getBit(key, offset); + } + + /** + * 批量获取 + * + * @param keys + * @return + */ + public List multiGet(Collection keys) { + return redisTemplate.opsForValue().multiGet(keys); + } + + /** + * 设置ASCII码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第offset位值变为value + * + * @param key 位置 + * @param value 值,true为1, false为0 + * @return + */ + public boolean setBit(String key, long offset, boolean value) { + return redisTemplate.opsForValue().setBit(key, offset, value); + } + + /** + * 将值 value 关联到 key ,并将 key 的过期时间设为 timeout + * + * @param key + * @param value + * @param timeout 过期时间 + * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES + * 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS + */ + public void setEx(String key, String value, long timeout, TimeUnit unit) { + redisTemplate.opsForValue().set(key, value, timeout, unit); + } + + /** + * 只有在 key 不存在时设置 key 的值 + * + * @param key + * @param value + * @return 之前已经存在返回false, 不存在返回true + */ + public boolean setIfAbsent(String key, String value) { + return redisTemplate.opsForValue().setIfAbsent(key, value); + } + + /** + * 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始 + * + * @param key + * @param value + * @param offset 从指定位置开始覆写 + */ + public void setRange(String key, String value, long offset) { + redisTemplate.opsForValue().set(key, value, offset); + } + + /** + * 获取字符串的长度 + * + * @param key + * @return + */ + public Long size(String key) { + return redisTemplate.opsForValue().size(key); + } + + /** + * 批量添加 + * + * @param maps + */ + public void multiSet(Map maps) { + redisTemplate.opsForValue().multiSet(maps); + } + + /** + * 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在 + * + * @param maps + * @return 之前已经存在返回false, 不存在返回true + */ + public boolean multiSetIfAbsent(Map maps) { + return redisTemplate.opsForValue().multiSetIfAbsent(maps); + } + + /** + * 增加(自增长), 负数则为自减 + * + * @param key + * @return + */ + public Long incrBy(String key, long increment) { + return redisTemplate.opsForValue().increment(key, increment); + } + + /** + * @param key + * @return + */ + public Double incrByFloat(String key, double increment) { + return redisTemplate.opsForValue().increment(key, increment); + } + + /** + * 追加到末尾 + * + * @param key + * @param value + * @return + */ + public Integer append(String key, String value) { + return redisTemplate.opsForValue().append(key, value); + } + + /** -------------------hash相关操作------------------------- */ + + /** + * 获取存储在哈希表中指定字段的值 + * + * @param key + * @param field + * @return + */ + public Object hGet(String key, String field) { + return redisTemplate.opsForHash().get(key, field); + } + + /** + * 获取所有给定字段的值 + * + * @param key + * @return + */ + public Map hGetAll(String key) { return redisTemplate.opsForHash().entries(key); } /** - * HashSet + * 获取所有给定字段的值 * - * @param key 键 - * @param map 对应多个键值 - * @return true 成功 false 失败 - */ - public boolean hmset(String key, Map 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 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) + * @param key + * @param fields * @return */ - public double hincr(String key, String item, double by) { - return redisTemplate.opsForHash().increment(key, item, by); + public List hMultiGet(String key, Collection fields) { + return redisTemplate.opsForHash().multiGet(key, fields); + } + + public void hPut(String key, String hashKey, String value) { + redisTemplate.opsForHash().put(key, hashKey, value); } /** - * hash递减 + * 存储带有过期时间的hashKey + * @param key + * @param hashKey + * @param value + * @param timeout + * @param unit + */ + public void hPutWithExpire(String key, String hashKey, String value, long timeout, TimeUnit unit) { + // 存储 hashKey 的值 + redisTemplate.opsForHash().put(key, hashKey, value); + // 计算过期时间的时间戳 + long expireAt = System.currentTimeMillis() + unit.toMillis(timeout); + // 使用 Sorted Set 存储过期时间 + redisTemplate.opsForZSet().add(key + ":expire", hashKey, expireAt); + } + + // 检查某个 hashKey 是否已经过期 + public boolean isHashKeyExpired(String key, String hashKey) { + Double score = redisTemplate.opsForZSet().score(key + ":expire", hashKey); + if (score != null) { + return System.currentTimeMillis() > score; + } + return false; + } + + public void hPutAll(String key, Map maps) { + redisTemplate.opsForHash().putAll(key, maps); + } + + /** + * 仅当hashKey不存在时才设置 * - * @param key 键 - * @param item 项 - * @param by 要减少记(小于0) + * @param key + * @param hashKey + * @param value * @return */ - public double hdecr(String key, String item, double by) { - return redisTemplate.opsForHash().increment(key, item, -by); + public Boolean hPutIfAbsent(String key, String hashKey, String value) { + return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value); } - // ============================Set(集合)============================= /** - * 根据key获取Set中的所有值 + * 删除一个或多个哈希表字段 * - * @param key 键 + * @param key + * @param fields * @return */ - public Set sGet(String key) { - try { - return redisTemplate.opsForSet().members(key); - } catch (Exception e) { - e.printStackTrace(); - return null; - } + public Long hDelete(String key, Object... fields) { + return redisTemplate.opsForHash().delete(key, fields); } /** - * 根据value从一个set中查询,是否存在 + * 查看哈希表 key 中,指定的字段是否存在 * - * @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 键 + * @param key + * @param field * @return */ - public long sGetSetSize(String key) { - try { - return redisTemplate.opsForSet().size(key); - } catch (Exception e) { - e.printStackTrace(); - return 0; - } + public boolean hExists(String key, String field) { + return redisTemplate.opsForHash().hasKey(key, field); } /** - * 移除值为value的 + * 为哈希表 key 中的指定字段的整数值加上增量 increment * - * @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代表所有值 + * @param key + * @param field + * @param increment * @return */ - public List lGet(String key, long start, long end) { - try { - return redisTemplate.opsForList().range(key, start, end); - } catch (Exception e) { - e.printStackTrace(); - return null; - } + public Long hIncrBy(String key, Object field, long increment) { + return redisTemplate.opsForHash().increment(key, field, increment); } /** - * 获取list缓存的长度 + * 为哈希表 key 中的指定字段的整数值加上增量 increment * - * @param key 键 + * @param key + * @param field + * @param delta * @return */ - public long lGetListSize(String key) { - try { - return redisTemplate.opsForList().size(key); - } catch (Exception e) { - e.printStackTrace(); - return 0; - } + public Double hIncrByFloat(String key, Object field, double delta) { + return redisTemplate.opsForHash().increment(key, field, delta); } /** - * 通过索引 获取list中的值 + * 获取所有哈希表中的字段 * - * @param key 键 - * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @param key * @return */ - public Object lGetIndex(String key, long index) { - try { - return redisTemplate.opsForList().index(key, index); - } catch (Exception e) { - e.printStackTrace(); - return null; - } + public Set hKeys(String key) { + return redisTemplate.opsForHash().keys(key); } /** - * 将list放入缓存 + * 获取哈希表中字段的数量 * - * @param key 键 - * @param value 值 + * @param key * @return */ - public boolean lSet(String key, Object value) { - try { - redisTemplate.opsForList().rightPush(key, value); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } + public Long hSize(String key) { + return redisTemplate.opsForHash().size(key); } /** - * 将list放入缓存 + * 获取哈希表中所有值 * - * @param key 键 - * @param value 值 - * @param time 时间(秒) + * @param key * @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; - } + public List hValues(String key) { + return redisTemplate.opsForHash().values(key); } /** - * 将list放入缓存 + * 迭代哈希表中的键值对 * - * @param key 键 - * @param value 值 + * @param key + * @param options * @return */ - public boolean lSet(String key, List value) { - try { - redisTemplate.opsForList().rightPushAll(key, value); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } + public Cursor> hScan(String key, ScanOptions options) { + return redisTemplate.opsForHash().scan(key, options); } + /** ------------------------list相关操作---------------------------- */ + /** - * 将list放入缓存 + * 通过索引获取列表中的元素 * - * @param key 键 - * @param value 值 - * @param time 时间(秒) + * @param key + * @param index * @return */ - public boolean lSet(String key, List value, long time) { - try { - redisTemplate.opsForList().rightPushAll(key, value); - if (time > 0) - expire(key, time); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } + public String lIndex(String key, long index) { + return (String) redisTemplate.opsForList().index(key, index); } /** - * 根据索引修改list中的某条数据 + * 获取列表指定范围内的元素 * - * @param key 键 - * @param index 索引 - * @param value 值 + * @param key + * @param start 开始位置, 0是开始位置 + * @param end 结束位置, -1返回所有 * @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; - } + public List lRange(String key, long start, long end) { + return redisTemplate.opsForList().range(key, start, end); } /** - * 移除N个值为value + * 存储在list头部 * - * @param key 键 - * @param count 移除多少个 - * @param value 值 - * @return 移除的个数 + * @param key + * @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; - } + public Long lLeftPush(String key, String value) { + return redisTemplate.opsForList().leftPush(key, value); } + + /** + * @param key + * @param value + * @return + */ + public Long lLeftPushAll(String key, String... value) { + return redisTemplate.opsForList().leftPushAll(key, value); + } + + /** + * @param key + * @param value + * @return + */ + public Long lLeftPushAll(String key, Collection value) { + return redisTemplate.opsForList().leftPushAll(key, value); + } + + /** + * 当list存在的时候才加入 + * + * @param key + * @param value + * @return + */ + public Long lLeftPushIfPresent(String key, String value) { + return redisTemplate.opsForList().leftPushIfPresent(key, value); + } + + /** + * 如果pivot存在,再pivot前面添加 + * + * @param key + * @param pivot + * @param value + * @return + */ + public Long lLeftPush(String key, String pivot, String value) { + return redisTemplate.opsForList().leftPush(key, pivot, value); + } + + /** + * @param key + * @param value + * @return + */ + public Long lRightPush(String key, String value) { + return redisTemplate.opsForList().rightPush(key, value); + } + + /** + * @param key + * @param value + * @return + */ + public Long lRightPushAll(String key, String... value) { + return redisTemplate.opsForList().rightPushAll(key, value); + } + + /** + * @param key + * @param value + * @return + */ + public Long lRightPushAll(String key, Collection value) { + return redisTemplate.opsForList().rightPushAll(key, value); + } + + /** + * 为已存在的列表添加值 + * + * @param key + * @param value + * @return + */ + public Long lRightPushIfPresent(String key, String value) { + return redisTemplate.opsForList().rightPushIfPresent(key, value); + } + + /** + * 在pivot元素的右边添加值 + * + * @param key + * @param pivot + * @param value + * @return + */ + public Long lRightPush(String key, String pivot, String value) { + return redisTemplate.opsForList().rightPush(key, pivot, value); + } + + /** + * 通过索引设置列表元素的值 + * + * @param key + * @param index 位置 + * @param value + */ + public void lSet(String key, long index, String value) { + redisTemplate.opsForList().set(key, index, value); + } + + /** + * 移出并获取列表的第一个元素 + * + * @param key + * @return 删除的元素 + */ + public String lLeftPop(String key) { + return (String) redisTemplate.opsForList().leftPop(key); + } + + /** + * 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 + * + * @param key + * @param timeout 等待时间 + * @param unit 时间单位 + * @return + */ + public String lBLeftPop(String key, long timeout, TimeUnit unit) { + return (String) redisTemplate.opsForList().leftPop(key, timeout, unit); + } + + /** + * 移除并获取列表最后一个元素 + * + * @param key + * @return 删除的元素 + */ + public String lRightPop(String key) { + return (String) redisTemplate.opsForList().rightPop(key); + } + + /** + * 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 + * + * @param key + * @param timeout 等待时间 + * @param unit 时间单位 + * @return + */ + public String lBRightPop(String key, long timeout, TimeUnit unit) { + return (String) redisTemplate.opsForList().rightPop(key, timeout, unit); + } + + /** + * 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 + * + * @param sourceKey + * @param destinationKey + * @return + */ + public String lRightPopAndLeftPush(String sourceKey, String destinationKey) { + return (String) redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, + destinationKey); + } + + /** + * 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 + * + * @param sourceKey + * @param destinationKey + * @param timeout + * @param unit + * @return + */ + public String lBRightPopAndLeftPush(String sourceKey, String destinationKey, + long timeout, TimeUnit unit) { + return (String) redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, + destinationKey, timeout, unit); + } + + /** + * 删除集合中值等于value得元素 + * + * @param key + * @param index index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; + * index<0, 从尾部开始删除第一个值等于value的元素; + * @param value + * @return + */ + public Long lRemove(String key, long index, String value) { + return redisTemplate.opsForList().remove(key, index, value); + } + + /** + * 裁剪list + * + * @param key + * @param start + * @param end + */ + public void lTrim(String key, long start, long end) { + redisTemplate.opsForList().trim(key, start, end); + } + + /** + * 获取列表长度 + * + * @param key + * @return + */ + public Long lLen(String key) { + return redisTemplate.opsForList().size(key); + } + + /** --------------------set相关操作-------------------------- */ + + /** + * set添加元素 + * + * @param key + * @param values + * @return + */ + public Long sAdd(String key, String... values) { + return redisTemplate.opsForSet().add(key, values); + } + + /** + * set移除元素 + * + * @param key + * @param values + * @return + */ + public Long sRemove(String key, Object... values) { + return redisTemplate.opsForSet().remove(key, values); + } + + /** + * 移除并返回集合的一个随机元素 + * + * @param key + * @return + */ + public String sPop(String key) { + return (String) redisTemplate.opsForSet().pop(key); + } + + /** + * 将元素value从一个集合移到另一个集合 + * + * @param key + * @param value + * @param destKey + * @return + */ + public Boolean sMove(String key, String value, String destKey) { + return redisTemplate.opsForSet().move(key, value, destKey); + } + + /** + * 获取集合的大小 + * + * @param key + * @return + */ + public Long sSize(String key) { + return redisTemplate.opsForSet().size(key); + } + + /** + * 判断集合是否包含value + * + * @param key + * @param value + * @return + */ + public Boolean sIsMember(String key, Object value) { + return redisTemplate.opsForSet().isMember(key, value); + } + + /** + * 获取两个集合的交集 + * + * @param key + * @param otherKey + * @return + */ + public Set sIntersect(String key, String otherKey) { + return redisTemplate.opsForSet().intersect(key, otherKey); + } + + /** + * 获取key集合与多个集合的交集 + * + * @param key + * @param otherKeys + * @return + */ + public Set sIntersect(String key, Collection otherKeys) { + return redisTemplate.opsForSet().intersect(key, otherKeys); + } + + /** + * key集合与otherKey集合的交集存储到destKey集合中 + * + * @param key + * @param otherKey + * @param destKey + * @return + */ + public Long sIntersectAndStore(String key, String otherKey, String destKey) { + return redisTemplate.opsForSet().intersectAndStore(key, otherKey, + destKey); + } + + /** + * key集合与多个集合的交集存储到destKey集合中 + * + * @param key + * @param otherKeys + * @param destKey + * @return + */ + public Long sIntersectAndStore(String key, Collection otherKeys, + String destKey) { + return redisTemplate.opsForSet().intersectAndStore(key, otherKeys, + destKey); + } + + /** + * 获取两个集合的并集 + * + * @param key + * @param otherKeys + * @return + */ + public Set sUnion(String key, String otherKeys) { + return redisTemplate.opsForSet().union(key, otherKeys); + } + + /** + * 获取key集合与多个集合的并集 + * + * @param key + * @param otherKeys + * @return + */ + public Set sUnion(String key, Collection otherKeys) { + return redisTemplate.opsForSet().union(key, otherKeys); + } + + /** + * key集合与otherKey集合的并集存储到destKey中 + * + * @param key + * @param otherKey + * @param destKey + * @return + */ + public Long sUnionAndStore(String key, String otherKey, String destKey) { + return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey); + } + + /** + * key集合与多个集合的并集存储到destKey中 + * + * @param key + * @param otherKeys + * @param destKey + * @return + */ + public Long sUnionAndStore(String key, Collection otherKeys, + String destKey) { + return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey); + } + + /** + * 获取两个集合的差集 + * + * @param key + * @param otherKey + * @return + */ + public Set sDifference(String key, String otherKey) { + return redisTemplate.opsForSet().difference(key, otherKey); + } + + /** + * 获取key集合与多个集合的差集 + * + * @param key + * @param otherKeys + * @return + */ + public Set sDifference(String key, Collection otherKeys) { + return redisTemplate.opsForSet().difference(key, otherKeys); + } + + /** + * key集合与otherKey集合的差集存储到destKey中 + * + * @param key + * @param otherKey + * @param destKey + * @return + */ + public Long sDifference(String key, String otherKey, String destKey) { + return redisTemplate.opsForSet().differenceAndStore(key, otherKey, + destKey); + } + + /** + * key集合与多个集合的差集存储到destKey中 + * + * @param key + * @param otherKeys + * @param destKey + * @return + */ + public Long sDifference(String key, Collection otherKeys, + String destKey) { + return redisTemplate.opsForSet().differenceAndStore(key, otherKeys, + destKey); + } + + /** + * 获取集合所有元素 + * + * @param key + * @return + */ + public Set setMembers(String key) { + return redisTemplate.opsForSet().members(key); + } + + /** + * 随机获取集合中的一个元素 + * + * @param key + * @return + */ + public String sRandomMember(String key) { + return (String) redisTemplate.opsForSet().randomMember(key); + } + + /** + * 随机获取集合中count个元素 + * + * @param key + * @param count + * @return + */ + public List sRandomMembers(String key, long count) { + return redisTemplate.opsForSet().randomMembers(key, count); + } + + /** + * 随机获取集合中count个元素并且去除重复的 + * + * @param key + * @param count + * @return + */ + public Set sDistinctRandomMembers(String key, long count) { + return redisTemplate.opsForSet().distinctRandomMembers(key, count); + } + + /** + * @param key + * @param options + * @return + */ + public Cursor sScan(String key, ScanOptions options) { + return redisTemplate.opsForSet().scan(key, options); + } + + /**------------------zSet相关操作--------------------------------*/ + + /** + * 添加元素,有序集合是按照元素的score值由小到大排列 + * + * @param key + * @param value + * @param score + * @return + */ + public Boolean zAdd(String key, String value, double score) { + return redisTemplate.opsForZSet().add(key, value, score); + } + + /** + * @param key + * @param values + * @return + */ + public Long zAdd(String key, Set> values) { + return redisTemplate.opsForZSet().add(key, values); + } + + /** + * @param key + * @param values + * @return + */ + public Long zRemove(String key, Object... values) { + return redisTemplate.opsForZSet().remove(key, values); + } + + /** + * 增加元素的score值,并返回增加后的值 + * + * @param key + * @param value + * @param delta + * @return + */ + public Double zIncrementScore(String key, String value, double delta) { + return redisTemplate.opsForZSet().incrementScore(key, value, delta); + } + + /** + * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列 + * + * @param key + * @param value + * @return 0表示第一位 + */ + public Long zRank(String key, Object value) { + return redisTemplate.opsForZSet().rank(key, value); + } + + /** + * 返回元素在集合的排名,按元素的score值由大到小排列 + * + * @param key + * @param value + * @return + */ + public Long zReverseRank(String key, Object value) { + return redisTemplate.opsForZSet().reverseRank(key, value); + } + + /** + * 获取集合的元素, 从小到大排序 + * + * @param key + * @param start 开始位置 + * @param end 结束位置, -1查询所有 + * @return + */ + public Set zRange(String key, long start, long end) { + return redisTemplate.opsForZSet().range(key, start, end); + } + + /** + * 获取集合元素, 并且把score值也获取 + * + * @param key + * @param start + * @param end + * @return + */ + public Set> zRangeWithScores(String key, long start, + long end) { + return redisTemplate.opsForZSet().rangeWithScores(key, start, end); + } + + /** + * 根据Score值查询集合元素 + * + * @param key + * @param min 最小值 + * @param max 最大值 + * @return + */ + public Set zRangeByScore(String key, double min, double max) { + return redisTemplate.opsForZSet().rangeByScore(key, min, max); + } + + /** + * 根据Score值查询集合元素, 从小到大排序 + * + * @param key + * @param min 最小值 + * @param max 最大值 + * @return + */ + public Set> zRangeByScoreWithScores(String key, + double min, double max) { + return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max); + } + + /** + * @param key + * @param min + * @param max + * @param start + * @param end + * @return + */ + public Set> zRangeByScoreWithScores(String key, + double min, double max, long start, long end) { + return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, + start, end); + } + + /** + * 获取集合的元素, 从大到小排序 + * + * @param key + * @param start + * @param end + * @return + */ + public Set zReverseRange(String key, long start, long end) { + return redisTemplate.opsForZSet().reverseRange(key, start, end); + } + + /** + * 获取集合的元素, 从大到小排序, 并返回score值 + * + * @param key + * @param start + * @param end + * @return + */ + public Set> zReverseRangeWithScores(String key, + long start, long end) { + return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, + end); + } + + /** + * 根据Score值查询集合元素, 从大到小排序 + * + * @param key + * @param min + * @param max + * @return + */ + public Set zReverseRangeByScore(String key, double min, + double max) { + return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max); + } + + /** + * 根据Score值查询集合元素, 从大到小排序 + * + * @param key + * @param min + * @param max + * @return + */ + public Set> zReverseRangeByScoreWithScores( + String key, double min, double max) { + return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, + min, max); + } + + /** + * @param key + * @param min + * @param max + * @param start + * @param end + * @return + */ + public Set zReverseRangeByScore(String key, double min, + double max, long start, long end) { + return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, + start, end); + } + + /** + * 根据score值获取集合元素数量 + * + * @param key + * @param min + * @param max + * @return + */ + public Long zCount(String key, double min, double max) { + return redisTemplate.opsForZSet().count(key, min, max); + } + + /** + * 获取集合大小 + * + * @param key + * @return + */ + public Long zSize(String key) { + return redisTemplate.opsForZSet().size(key); + } + + /** + * 获取集合大小 + * + * @param key + * @return + */ + public Long zZCard(String key) { + return redisTemplate.opsForZSet().zCard(key); + } + + /** + * 获取集合中value元素的score值 + * + * @param key + * @param value + * @return + */ + public Double zScore(String key, Object value) { + return redisTemplate.opsForZSet().score(key, value); + } + + /** + * 移除指定索引位置的成员 + * + * @param key + * @param start + * @param end + * @return + */ + public Long zRemoveRange(String key, long start, long end) { + return redisTemplate.opsForZSet().removeRange(key, start, end); + } + + /** + * 根据指定的score值的范围来移除成员 + * + * @param key + * @param min + * @param max + * @return + */ + public Long zRemoveRangeByScore(String key, double min, double max) { + return redisTemplate.opsForZSet().removeRangeByScore(key, min, max); + } + + /** + * 获取key和otherKey的并集并存储在destKey中 + * + * @param key + * @param otherKey + * @param destKey + * @return + */ + public Long zUnionAndStore(String key, String otherKey, String destKey) { + return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey); + } + + /** + * @param key + * @param otherKeys + * @param destKey + * @return + */ + public Long zUnionAndStore(String key, Collection otherKeys, + String destKey) { + return redisTemplate.opsForZSet() + .unionAndStore(key, otherKeys, destKey); + } + + /** + * 交集 + * + * @param key + * @param otherKey + * @param destKey + * @return + */ + public Long zIntersectAndStore(String key, String otherKey, + String destKey) { + return redisTemplate.opsForZSet().intersectAndStore(key, otherKey, + destKey); + } + + /** + * 交集 + * + * @param key + * @param otherKeys + * @param destKey + * @return + */ + public Long zIntersectAndStore(String key, Collection otherKeys, + String destKey) { + return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, + destKey); + } + + /** + * @param key + * @param options + * @return + */ + public Cursor> zScan(String key, ScanOptions options) { + return redisTemplate.opsForZSet().scan(key, options); + } + } - diff --git a/YuNan-system-start/src/main/resources/application.yml b/YuNan-system-start/src/main/resources/application.yml index 51c86a0..971212e 100644 --- a/YuNan-system-start/src/main/resources/application.yml +++ b/YuNan-system-start/src/main/resources/application.yml @@ -1,4 +1,3 @@ - spring: application: name: YuNan-demo @@ -11,7 +10,10 @@ spring: pathmatch: matching-strategy: ant-path-matcher +--- + #****************************mail*************************** +spring: mail: # SMTP服务器,这个是QQ邮箱的 其他邮箱请另行百度 host: smtp.qq.com @@ -37,9 +39,10 @@ spring: # 邮件发送时间的限制,单位毫秒 writetimeout: 10000 - +--- #****************************Redis*************************** +spring: redis: host: localhost # Redis 服务器地址 port: 6379 # Redis 服务器端口 diff --git a/YuNan-system-start/src/main/resources/mapper/AuthMapper.xml b/YuNan-system-start/src/main/resources/mapper/AuthMapper.xml new file mode 100644 index 0000000..8182f21 --- /dev/null +++ b/YuNan-system-start/src/main/resources/mapper/AuthMapper.xml @@ -0,0 +1,11 @@ + + + + + + insert into users (username, password, email) values (#{username}, #{password}, #{email}) + + + \ No newline at end of file