SpringBoot校验手机验证码案例:默认缓存、Ehcache缓存、数据淘汰策略、redis缓存

目录

一 默认缓存

1.1 主要代码

1.2 测试

二 Ehcache缓存

三 数据淘汰策略

 四 redis缓存

4.1 基础使用

4.2 其他配置


本案例实现功能:

1 根据手机号码生成6位数的数字验证码

2 输入手机号和验证码,判断输入的验证码是否正确

一 默认缓存

1.1 主要代码

1 添加依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>


2 启用缓存

3 实体类

package com.qing.bean;

import lombok.Data;

@Data
public class SMSCode {

    private String phoneNum;
    private String code;

}


4 创建验证码的工具类

package com.qing.util;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class CodeUtils {
    public String generate(String phoneNum) {
        int hash = phoneNum.hashCode();
        int encryption = 2022630;
        //异或加密:一种通过异或运算进行加密的算法
        //转成二进制,运算规则:相同为0,不同为1,再转成十进制
        long result = hash ^ encryption;
        long nowTime = System.currentTimeMillis();
        result = result ^ nowTime;
        long code = result % 1000000;
        //处理有负数的情况
        code = code < 0 ? -code : code;
        //六位数:前面补0
        String.format("%06d",code);
        return code + "";
    }

    //获取缓存里的验证码
    @Cacheable(key ="#phoneNum" ,value = "cacheCode")
    public String getCacheCode(String phoneNum){
        return null;
    }
}

关于异或运算请点这里

说明:getCacheCode()获取缓存里的验证码的方法,写在工具类这里是因为要使spring的@Cacheable这个注解生效,需要注入spring容器,该工具类在后面的ServiceImpl进行了注入,该方法返回的是注解@Cacheable的value属性值 → cacheCode (详见后面的测试)

5 service

package com.qing.service;

import com.qing.bean.SMSCode;

public interface SMSCodeService {

    //发送验证码
    String sendCode(String phoneNum);
    //检查验证码
    boolean checkCode(SMSCode smsCode);
}


6 serviceImpl

package com.qing.service.impl;

import com.qing.bean.SMSCode;
import com.qing.service.SMSCodeService;
import com.qing.util.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {


    @Autowired
    CodeUtils codeUtils;

    //发送验证码
    @Override
    //只往里放,不往外读
    @CachePut(key = "#phoneNum", value = "cacheCode")
    public String sendCode(String phoneNum) {
        return codeUtils.generate(phoneNum);
    }


    //比对验证码
    @Override
    public boolean checkCode(SMSCode smsCode) {
        //取出内存中的验证码与传递过来的验证码比对,相同返回true
        String code = smsCode.getCode();
        String cacheCode = codeUtils.getCacheCode(smsCode.getPhoneNum());
        return code.equals(cacheCode);
    }
}


7 controller

package com.qing.controller;

import com.qing.bean.SMSCode;
import com.qing.service.SMSCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/sms")
public class SMSCodeController {

    @Autowired
    private SMSCodeService smsCodeService;

    @GetMapping("/{phoneNum}")
    public String getCode(@PathVariable String phoneNum){

        return smsCodeService.sendCode(phoneNum);
    }

    @PostMapping
    public boolean checkCode(@RequestBody SMSCode smsCode) {
        return smsCodeService.checkCode(smsCode);
    }
}

1.2 测试

1 生成验证码

 2 输入错的验证码验证

 

 3 输入正确的验证码

 4 再次生成验证

二 Ehcache缓存

在默认缓存案例的基础上做3个配置就行

1 加依赖

       <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

2 配置文件

 3 ehcache.xml放在resources下

默认缓存

 配置新的缓存:name要和@CachePut注解的的value的属性值一样

 

三 数据淘汰策略

下图表示的信息:

1 下面的时间分别表示最后一次访问是第几秒访问的

2 上面的数字表示访问了几次

LRU:age → 是上次访问离现在的时间最远的

LFU:gender → 访问次数最少的

 四 redis缓存

4.1 基础使用

在默认缓存的基础加2个配置

1 导入依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2 配置文件

 测试

打开redis的服务端和客户端

关于redis的安装和简单使用在这里

生成一次验证码

 数据已经进到redis缓存里了

 把缓存的名字即这个value属性的值 和 key 电话号码组合成一个新的key一起放进redis缓存里

 再生成一次验证码

redis又多了一个缓存数据

4.2 其他配置

 测有效时间 10s

 看一下测试效果

 10s之后缓存里的验证码失效了

 备注:超过了有效时长,redis数据里就没有那个缓存了​​​​​​​

 测前缀

 

 总结

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是Spring Boot整合Ehcache解决Mybatis二级缓存数据脏读的详细步骤: 1. 添加依赖 首先,需要在pom.xml文件中添加EhcacheSpring Boot的相关依赖: ``` <!-- Ehcache依赖 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.6</version> </dependency> <!-- Spring Boot依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> ``` 2. 配置Ehcache 在src/main/resources目录下创建ehcache.xml文件,并添加以下配置: ``` <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false"> <!-- 默认缓存配置 --> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="true"> </defaultCache> <!-- Mybatis二级缓存配置 --> <cache name="com.example.demo.mapper.UserMapper" maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="true"> </cache> </ehcache> ``` 在配置文件中,我们定义了默认缓存配置和针对UserMapper的缓存配置。 3. 配置Mybatis 在application.properties中添加Mybatis相关配置: ``` # Mybatis配置 mybatis.type-aliases-package=com.example.demo.entity mybatis.mapper-locations=classpath:mapper/*.xml mybatis.configuration.cache-enabled=true mybatis.configuration.local-cache-scope=session mybatis.configuration.cache-ref=ehcache ``` 注意,cache-enabled属性设置为true,local-cache-scope属性设置为session,并指定了使用的缓存提供者为Ehcache。 4. 配置缓存管理器 在启动类中配置缓存管理器: ``` @Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { EhCacheCacheManager cacheManager = new EhCacheCacheManager(); cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject()); return cacheManager; } @Bean public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() { EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean(); cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); cacheManagerFactoryBean.setShared(true); return cacheManagerFactoryBean; } } ``` 在这里,我们通过EhCacheCacheManager和EhCacheManagerFactoryBean来配置缓存管理器。 5. 开启缓存 最后,在Mapper接口中开启缓存: ``` @CacheNamespace(implementation = net.sf.ehcache.Cache.class, eviction = FifoPolicy.class) public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") @Options(useCache = true, flushCache = Options.FlushCachePolicy.FALSE, timeout = 10000) User selectById(Integer id); @Update("UPDATE user SET name = #{name} WHERE id = #{id}") void updateNameById(@Param("id") Integer id, @Param("name") String name); } ``` 使用@CacheNamespace注解来指定缓存实现类和缓存策略,在每个查询方法上使用@Options注解来开启缓存。 至此,Spring Boot整合Ehcache解决Mybatis二级缓存数据脏读的配置就完成了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值