• 优化------聊聊缓存


    目录

    1.创建仓库

    2.提交到远程仓库

    3.创建分支

    4.环境配置

    5.缓存

    1.短信验证码缓存

    2.数据缓存

    1.对数据进行缓存

    2.清除缓存

    6.合并分支

    方法一:使用git命令合并

    方法二:

    7.qq邮箱实现验证码的发送

    1.在qq邮箱开启POP3/SMTP服务

    2.添加邮箱依赖

    3.创建发送邮箱工具类

    4.创建随机生成验证码的工具类

    5.创建IndexController

    6.简单的view

    7.简单的测试页面login.html

    8.最近总结


    对数据进行缓存,降低数据库被查询的压力

    在高并发的情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长,所以需要对方法进行优化,提高系统的性能。

    下面关于git分支类的大家可以直接省略

    1.创建仓库

    码云:Gitee - 基于 Git 的代码托管和研发协作平台

    2.提交到远程仓库

    • 来到本地仓库

    •  选择要提交的项目即可
    • 先看一下要提交的项目有没有.gitignore文件
    • 没有的话在git添加一个
    • 这个是我的:
    1. .git
    2. logs
    3. rebel.xml
    4. target/
    5. !.mvn/wrapper/maven-wrapper.jar
    6. log.path_IS_UNDEFINED
    7. .DS_Store
    8. offline_user.md
    9. ### STS ###
    10. .apt_generated
    11. .classpath
    12. .factorypath
    13. .project
    14. .settings
    15. .springBeans
    16. ### IntelliJ IDEA ###
    17. .idea
    18. *.iws
    19. *.iml
    20. *.ipr
    21. ### NetBeans ###
    22. nbproject/private/
    23. build/
    24. nbbuild/
    25. dist/
    26. nbdist/
    27. .nb-gradle/
    28. generatorConfig.xml
    29. ### nacos ###
    30. third-party/nacos/derby.log
    31. third-party/nacos/data/
    32. third-party/nacos/work/
    33. file/

    因为项目git初始化之后源码文件会都变成红色,所以在根目录右键点击添加(如下) 

    之后进行正常的commit和push就OK了,详解见提交到远程仓库_雾喔的博客-CSDN博客_提交到远程仓库 

    刷新码云仓库界面,就可以看到项目成功提交上去了。

    3.创建分支

    • 因为项目优化是在分支上做的,所以最后优化完成之后会将分支合并到主分支上
    • 右键
    • 或者点击idea右下角

     

    • 就可以新建一个分支了
    • 之后再将分支push上去就OK啦
    • 刷新页面会看到

     

    4.环境配置

    导入依赖:

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-data-redis</artifactId>
    4. <version>2.7.5</version>
    5. </dependency>

     大家可以去maven仓库找最新版本

    https://mvnrepository.com/

    • 在项目的application.yml中加入redis相关配置:
    1. spring:
    2. redis:
    3. host: ip地址(本地的话就是localhost)
    4. port: 6379(端口号)
    5. password: redis密码
    6. database: redis仓库
    • 在config下新建一个配置类
    1. import org.springframework.cache.annotation.CachingConfigurerSupport;
    2. import org.springframework.context.annotation.Bean;
    3. import org.springframework.context.annotation.Configuration;
    4. import org.springframework.data.redis.connection.RedisConnectionFactory;
    5. import org.springframework.data.redis.core.RedisTemplate;
    6. import org.springframework.data.redis.serializer.StringRedisSerializer;
    7. /**
    8. * @author a1002
    9. */
    10. @Configuration
    11. public class RedisConfig extends CachingConfigurerSupport {
    12. @Bean
    13. public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
    14. RedisTemplate redisTemplate = new RedisTemplate<>();
    15. //默认的Key序列化器为:JdkSerializationRedisSerializer
    16. redisTemplate.setKeySerializer(new StringRedisSerializer());
    17. redisTemplate.setConnectionFactory(connectionFactory);
    18. return redisTemplate;
    19. }
    20. }

    5.缓存

    1.短信验证码缓存

    • 发送手机验证码的controller层
    • 注入RedisTemplate
      1. @Autowired
      2. private RedisTemplate redisTemplate;

      发送验证码的接口:

      1. //将生成的验证码缓存到redis,并且设置有效期为五分钟
      2. redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES);

    • 验证码有效期为五分钟,所以为

      TimeUnit.MINUTES

     在登录接口加上:

    1. //从redis获取缓存的验证码
    2. Object codeInSession = redisTemplate.opsForValue().get(phone);

    如果登录成功:

    1. //如果用户登录成功,删除redis中缓存的验证码
    2. redisTemplate.delete(phone);

    2.数据缓存

    对数据进行缓存,降低数据库被查询的压力,有数据被执行save或update方法时要清理缓存。

    在使用缓存过程中,要注意保证数据库中的数据和缓存中的数据一致,如果数据库中的数据发生变化,需要及时清理缓存。

    1.对数据进行缓存

    在查询数据库中数据的接口加上(Get):

    1. List dishDtoList = null;
    2. String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();
    3. //先从redis中获取数据
    4. dishDtoList = (List) redisTemplate.opsForValue().get(key);
    5. if (dishDtoList != null) {
    6. //如果存在,无需再查询数据库
    7. return R.success(dishDtoList);
    8. }

    下面的步骤是正常的从数据库查询数据

    在方法最后面加上:

    1. //如果不存在,需要查询数据库,将查询到的数据缓存到Redis中
    2. redisTemplate.opsForValue().set(key, dishDtoList, 60, TimeUnit.MINUTES);

    设置的有效时间为一个小时。

    2.清除缓存

    在使用缓存过程中,要注意保证数据库中的数据和缓存中的数据一致,如果数据库中的数据发生变化,需要及时清理缓存数据。

    方法一:

    清除所有的同类缓存

    1. //清理所有的菜品的缓存数据
    2. Set keys=redisTemplate.keys("dish_*");
    3. redisTemplate.delete(keys);

    方法二:

    精确清理某个分类下的菜品缓存

    1. String key="dish_"+dishDto.getCategoryId()+"_1";
    2. redisTemplate.delete(key);

    关于缓存的进一步了解的话大家可以去了解一下Spring Cache

    Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单的加一个注解,就能实现缓存功能。

    spring cache提供了一层抽象,底层可以切换不同的cache实现,具体就是通过CacheManager接口来统一不同的缓存技术。

    6.合并分支

    合并分支之前需要保证分支没有问题

    方法一:使用git命令合并

    •  切换到master分支上
    git checkout master
    • 确保master代码是最新的代码
    git pull origin master
    • 然后我们把v1.0分支的代码合并到master上
    git merge v1.0
    • 然后查看状态及执行提交命令
    git status

    方法二:

    • 点击右下角

    • 切换到master
    • 拉取项目 

     时把v1.0分支选上

    ---------------------------------------------------------------------------------------------------------------------------------

     --------------------------------------------------------------------------------------------------------------------------------

    -------------------------------------------------我是可爱的分割线--------------------------------------------------------

    ---------------------------------------------------------------------------------------------------------------------------------

     --------------------------------------------------------------------------------------------------------------------------------

    7.qq邮箱实现验证码的发送

    1.在qq邮箱开启POP3/SMTP服务

    QQ邮箱

     按照指示操作获取授权码

    2.添加邮箱依赖

    1. org.springframework.boot
    2. spring-boot-starter-mail
    3. 2.7.4

    这个是大致目录:

    3.创建发送邮箱工具类

    1. import com.sun.mail.util.MailSSLSocketFactory;
    2. import javax.mail.*;
    3. import javax.mail.internet.InternetAddress;
    4. import javax.mail.internet.MimeMessage;
    5. import java.util.Properties;
    6. public class MailUtils {
    7. //发送第二封验证码邮件
    8. public static void sendMail(String to, String vcode) throws Exception {
    9. //设置发送邮件的主机 smtp.qq.com
    10. String host = "smtp.qq.com";
    11. //1.创建连接对象,连接到邮箱服务器
    12. Properties props = System.getProperties();
    13. //Properties 用来设置服务器地址,主机名 。。 可以省略
    14. //设置邮件服务器
    15. props.setProperty("mail.smtp.host", host);
    16. props.put("mail.smtp.auth", "true");
    17. //SSL加密
    18. MailSSLSocketFactory sf = new MailSSLSocketFactory();
    19. sf.setTrustAllHosts(true);
    20. props.put("mail.smtp.ssl.enable", "true");
    21. props.put("mail.smtp.ssl.socketFactory", sf);
    22. //props:用来设置服务器地址,主机名;Authenticator:认证信息
    23. Session session = Session.getDefaultInstance(props, new Authenticator() {
    24. @Override
    25. //通过密码认证信息
    26. protected PasswordAuthentication getPasswordAuthentication() {
    27. //new PasswordAuthentication(用户名, password);
    28. //这个用户名密码就可以登录到邮箱服务器了,用它给别人发送邮件
    29. return new PasswordAuthentication("2728XXXXX8@qq.com", "thklbwsdgtkpdghb");
    30. }
    31. });
    32. try {
    33. Message message = new MimeMessage(session);
    34. //2.1设置发件人:
    35. message.setFrom(new InternetAddress("27287XXXX38@qq.com"));
    36. //2.2设置收件人 这个TO就是收件人
    37. message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
    38. //2.3邮件的主题
    39. message.setSubject("来自黑客星球网站验证码邮件");
    40. //2.4设置邮件的正文 第一个参数是邮件的正文内容 第二个参数是:是文本还是html的连接
    41. message.setContent("

      来自黑客星球的网站验证码邮件,请接收你的成神验证码:

      你的验证码是:" + vcode + ",请妥善保管好你的验证码!

      "
      , "text/html;charset=UTF-8");
    42. //3.发送一封激活邮件
    43. Transport.send(message);
    44. } catch (MessagingException mex) {
    45. mex.printStackTrace();
    46. }
    47. }
    48. }

    4.创建随机生成验证码的工具类

    1. import java.util.Random;
    2. /**
    3. * 随机生成验证码工具类
    4. *
    5. * @author a1002
    6. */
    7. public class ValidateCodeUtils {
    8. /**
    9. * 随机生成验证码
    10. *
    11. * @param length 长度为4位或者6位
    12. * @return
    13. */
    14. public static Integer generateValidateCode(int length) {
    15. Integer code = null;
    16. if (length == 4) {
    17. code = new Random().nextInt(9999);//生成随机数,最大为9999
    18. if (code < 1000) {
    19. code = code + 1000;//保证随机数为4位数字
    20. }
    21. } else if (length == 6) {
    22. code = new Random().nextInt(999999);//生成随机数,最大为999999
    23. if (code < 100000) {
    24. code = code + 100000;//保证随机数为6位数字
    25. }
    26. } else {
    27. throw new RuntimeException("只能生成4位或6位数字验证码");
    28. }
    29. return code;
    30. }
    31. /**
    32. * 随机生成指定长度字符串验证码
    33. *
    34. * @param length 长度
    35. * @return
    36. */
    37. public static String generateValidateCode4String(int length) {
    38. Random rdm = new Random();
    39. String hash1 = Integer.toHexString(rdm.nextInt());
    40. String capstr = hash1.substring(0, length);
    41. return capstr;
    42. }
    43. }

    5.创建IndexController

    1. import com.mailredistest.utils.MailUtils;
    2. import com.mailredistest.utils.ValidateCodeUtils;
    3. import lombok.extern.slf4j.Slf4j;
    4. import org.apache.maven.surefire.shade.org.apache.commons.lang3.StringUtils;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.data.redis.core.RedisTemplate;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.web.bind.annotation.PostMapping;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import org.springframework.web.servlet.ModelAndView;
    11. import java.util.concurrent.TimeUnit;
    12. /**
    13. * @author a1002
    14. */
    15. @Controller
    16. @RequestMapping("/user")
    17. @Slf4j
    18. public class IndexController {
    19. @Autowired
    20. private RedisTemplate redisTemplate;
    21. /**
    22. * 用户登录
    23. */
    24. @PostMapping("/login")
    25. public ModelAndView login(String mail, String code) {
    26. ModelAndView mv = new ModelAndView();
    27. // log.info(code.toString());
    28. //从Session中获取保存的验证码
    29. // Object codeInSession = session.getAttribute(phone);
    30. //从redis获取缓存的验证码
    31. Object codeInSession = redisTemplate.opsForValue().get(mail);
    32. //进行验证码的比对(页面提交的验证码和Session中保存的验证码比对)
    33. if (codeInSession != null && codeInSession.equals(code)) {
    34. //如果能够比对成功,说明登录成功
    35. //如果用户登录成功,删除redis中缓存的验证码
    36. redisTemplate.delete(mail);
    37. log.info("==================登录成功!====================");
    38. mv.setViewName("index");
    39. return mv;
    40. }
    41. mv.setViewName("login");
    42. return mv;
    43. }
    44. /**
    45. * 发送手机短信验证码
    46. */
    47. @PostMapping("/sendMsg")
    48. public ModelAndView sendMsg(String mail) throws Exception {
    49. log.info("============{}========", mail);
    50. ModelAndView mv = new ModelAndView();
    51. if (StringUtils.isNotEmpty(mail)) {
    52. //生成随机的4位验证码
    53. String code = ValidateCodeUtils.generateValidateCode(4).toString();
    54. log.info("code={}", code);
    55. MailUtils.sendMail(mail, code);
    56. //将生成的验证码缓存到redis,并且设置有效期为30秒
    57. redisTemplate.opsForValue().set(mail, code, 30, TimeUnit.SECONDS);
    58. }
    59. mv.setViewName("login");
    60. return mv;
    61. }
    62. }

    6.简单的view

    1. import org.springframework.stereotype.Controller;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. /**
    4. * @author a1002
    5. */
    6. @Controller
    7. public class View {
    8. @RequestMapping("/index")
    9. public String q2() {
    10. return "/index";
    11. }
    12. @RequestMapping("/login")
    13. public String q1() {
    14. return "/login";
    15. }
    16. }

    7.简单的测试页面login.html

    1. html>
    2. <html xmlns:th="http://www.thymeleaf.org">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>logintitle>
    6. head>
    7. <body>
    8. <form th:action="@{/user/sendMsg}" method="post">
    9. <input class="up" type="text" name="mail" placeholder="邮箱" required>
    10. <input type="submit" class="login" name="发送验证码">
    11. form>
    12. <form th:action="@{/user/login}" method="post">
    13. <input class="up" type="text" name="mail" placeholder="邮箱" required>
    14. <input class="down" type="text" name="code" placeholder="验证码" required>
    15. <input type="submit" class="login" name="登录">
    16. form>
    17. body>
    18. html>

    ---------------------------------------------------------------------------------------------------------------------------------

     --------------------------------------------------------------------------------------------------------------------------------

    -------------------------------------------------我是可爱的分割线鸭-----------------------------------------------------

    ---------------------------------------------------------------------------------------------------------------------------------

     --------------------------------------------------------------------------------------------------------------------------------

    8.最近总结

    很开心小组新增了很多大一的孩子。

    最近也发生一个比较有意思的事情,当然最后这些都会成为回忆。

    最近也挺烦恼的,拿不了快递。

    最近惰性有点强。

    最近有了一个新的体悟,假如在某件事或某个人上投入太多的精力,事后后劲虽然会有一段时间挺大,但之后的很长一段时间后劲就会变得异常绵长和断断续续,就是那种以为自己忘了,实则不然。

    最后祝我越来越好🎉

    ---------------------------------------------------------------------------------------------------------------------------------

     --------------------------------------------------------------------------------------------------------------------------------

    -------------------------------------------------我是可爱的分割线鸭-----------------------------------------------------

    ---------------------------------------------------------------------------------------------------------------------------------

     --------------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    计算机组成原理——存储系统の选择题整理
    Redis:StringRedisTemplate简介
    【web前端期末大作业】制作一个HTML+CSS保护动物宠物网页
    内存池的C实现
    输电线路分布式故障监测装置:准确定位故障点、辨识故障原因
    Spring Boot 配置文件
    【Android性能优化】:ProGuard,混淆,R8优化
    Python基础知识从hello world 开始(第四天完结)
    ubuntu Setforeground 前台应用切换
    Summary,Cache,Counter表的使用
  • 原文地址:https://blog.csdn.net/Hubery_sky/article/details/127673556