一、什么是redis?

Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSIC编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库

二、Redis的数据类型

Redis提供的数据类型主要分为5种自有类型和一种自定义类型,这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和顺序集合类型。

三、什么是swagger?

Swagger是一个开放源代码软件框架,由大型工具生态系统支持,可帮助开发人员设计,构建,记录和使用RESTful Web服务。

在这里,主要为大家介绍一下当用户登录某网站时怎么进行redis存储信息。首先逻辑如下:

当用户输入用户名和密码后,去redis里面查看是否存在登录时用户的信息,如果有则从redis里面获取;如果不存在,则从数据库中获取信息,并存入redis缓存当中。在这里我使用swagger进行测试,所以要去配置文件当中添加相应的条件依赖。

pom.xml配置文件

<dependency>
   <groupId>io.springfox</groupId> 
   <artifactId>springfox-swagger2</artifactId> 
   <version>2.9.2</version> 
</dependency> 
<dependency> 
   <groupId>io.springfox</groupId> 
   <artifactId>springfox-swagger-ui</artifactId> 
   <version>2.9.2</version> 
</dependency> 
<dependency> 
   <groupId>net.minidev</groupId> 
   <artifactId>json-smart</artifactId> 
</dependency> 
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-web</artifactId> 
</dependency>

<dependency>

   <groupId>mysql</groupId>

   <artifactId>mysql-connector-java</artifactId> </dependency>

application.yml配置

# 使用swagger必须要写这个,不然会报错
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  redis:
    # 设定连接超时时间 默认为100ms
    connect-timeout: 10ms
    # spring 默认使用的是lettuce连接池,配置连接池相关属性
    lettuce:
      pool:
        # 连接池在给定实践内可分配的最大连接数 默认8。负数表示无限
        max-active: 8
        # 当连接池耗尽时,在抛出异常之前,连接分配应该阻塞的最大时间。默认-1,表示无限阻塞。
        max-wait: 10ms
        # 连接池里维护的最大空闲连接数。使用负值表示无限制。 默认8
        max-idle: 200
        # 连接池里维护的最小空闲连接数 默认0
        min-idle: 5
  # 配置数据源
  datasource:

  #数据库驱动
    driver-class-name: com.mysql.cj.jdbc.Driver

    #数据库用户名
    username: root  

    #数据库密码
    password: root

    #表示连接的某个数据库
    url: jdbc:mysql://localhost:3306/jpa_db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
 

由于此处还使用的lambok插件,因此也要在配置文件中添加,才能使用@Data注解。

pom.xml配置文件中添加以下内容:

<dependency>         <groupId>org.projectlombok</groupId>   <artifactId>lombok</artifactId>   <optional>true</optional> </dependency> 

实体类BaseModel

/**
 * 提取model中的公共参数
 * */
@Data
public class BaseModel {
    private Date start;
    private Date end;
    private Integer page;
    private Integer pageSize;

}

实体类User

@Data

@ApiModel(value = "用户对象",description = "用于描述用户对象")

public class User extends BaseModel implements Serializable {

  @ApiModelProperty(value = "用户Id",example = "3")

  private Integer uId;

  @ApiModelProperty(value = "用户姓名",example = "lisa")

  private String uName;

  @ApiModelProperty(value = "用户密码",example = "211327")

  private String uPwd;

  @ApiModelProperty(value = "用户性别",example = "女")

  private String uSex;

  @ApiModelProperty(value = "用户生日",example = "2002-01-03")

  private Date uBirthday;

  @ApiModelProperty(value = "用户电话",example = "13045007800")

  private String uPhone;

  @ApiModelProperty(value = "用户地址",example = "四川省xx市")

  private String uAddress;

  @ApiModelProperty(value = "用户爱好",example = "游戏,看书")

  private String uHobby;

  @ApiModelProperty(value = "用户邮箱",example = "2236971973@qq.com")

  private String uEmail;

  @ApiModelProperty(value = "用户状态",example = "1")

  private Integer state;

}

注解说明

@Api :用于标注一个Controller(Class)。在默认情况下,Swagger-Core只会扫描解析具有@Api注解的类。其中主要的属性有:

value:url的路径值
tags :如果设置这个值、value的值会被覆盖
description :对api资源的描述

@ApiOperation :在用于对一个操作或HTTP方法进行描述。具有相同路径的不同操作会被归组为同一个操作对象。不同的HTTP请求方法及路径组合构成一个唯一操作。

@ApiModel:用于描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)。

@ApiModelProperty:用来描述一个Model的属性。

@RequestParam用于获取前端传过来的参数,可以是get、post请求,也就是url中"?"后面拼接的每个参数。

UserMapper

/**根据用户名及密码查询用户数据实现登录*/
@Select("select * from user where u_name=#{uName} and u_pwd=#{uPwd}")
User selectUserByNameAndPwd(User user);

UserServiceImpl

在这里我们使用logback,但是这里没有详细介绍,后续作者再进行详细补充说明其中的概念自己它的好处。

private static Logger logger = (Logger) LoggerFactory.getLogger(UserServiceImpl.class.getName());
    @Autowired
    private UserMapper userMapper;
    @Resource
    ResultModel resultModel;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public ResultModel getUserByNameAndPwd(User user, HttpServletResponse response) {
        //判定用户名及密码
        if (StringUtils.isEmpty(user.getUName()) || StringUtils.isEmpty(user.getUPwd())) {
            return ResultModel.getErrorResultModel(ErrorMsgEnumn.ERROR_NULL_USERNAME_PWD);
        }
        //根据用户名及密码判定用户是否存在
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String key = "LoginUserInfo:" + user.getUName();
        //判断redis里面是否有用户数据
        User u = (User) valueOperations.get(key);
        //如果redis当中存在登陆的用户信息,就从redis拿数据
        if (u != null) {
            user = u;
            logger.info("使用redis获取登录用户数据");
        } else {  //如果redis当中不存在登陆的用户信息,就从数据库拿数据,并存入redis当中
            user = userMapper.selectUserByNameAndPwd(user);
            valueOperations.set(key, user);
            logger.info("使用数据库获取用户信息");
        }
        ResultModel resultModel = ResultModel.getSingleResultModel(user);
        //用户控制器带上token响应头,如不设置,前端无法接收响应头数据。
        response.setHeader("Access-Control-Expose-Headers", "token");
        //设置token相应头
        response.setHeader("token", key);

        //用户登陆成功后,发送登陆成功邮件
        SendEmail send = new SendEmail();
        send.start();
        send.sendEmail(user.getUEmail());
        return resultModel;
    }

UserController

@RequestMapping(value = "/login")

    @ApiOperation(value = "登录用户",response = User.class,httpMethod = "POST")

    public ResultModel login(@Validated User user, BindingResult bindingResult, HttpServletResponse response){

        /**获取校验的异常信息*/

        List<String> errorMsgList = new ArrayList<>();

        if (bindingResult.hasErrors()) {

            //校验未通过,获取所有的异常信息并展示出来

            List<ObjectError> allErrors = bindingResult.getAllErrors();

            for (ObjectError allError : allErrors) {

        errorMsgList.add(allError.getDefaultMessage());

            }

        }

        if(errorMsgList.size() > 0){

            ResultModel resultModel = ResultModel.getErrorResultModel(errorMsgList);

            return resultModel;

        }

        user.setUName(user.getUName());

 user.setUPwd(MD5Utils.getPWD(user.getUPwd()));

        ResultModel resultModel = userService.getUserByNameAndPwd(user, response);

        return resultModel;

    }

大致的代码实现流程就是这样,也许不完善,大家可以根据自己的情况修改。在这里我们首先去看看redis缓存中有些什么信息。

147e4cf86e2d442c8124f959b546d882.jpg

 从中看出这里只有一个用户的信息,那我们使用swagger进行登录测试,看看登录结果到底如何

swagger2.x访问地址:

http://localhost:8080/swagger-ui.html

f30483a8185a4bfe966ea304aab2a67f.jpg

 在这里我们选择登录用户,里面有很多属性,在这里我们只需要用到用户名和密码即可,因此我们拿一个数据库里面有的数据来测试一下。

首先点击Try it out进行测试

ec2a578eba244122b23611c6a69ac913.jpg

 然后输入用户名和密码

3c736ff860504d13a8e3479924ea0a43.jpg

 测试结果

ebf05582116c449b89016225dcdcdf5b.jpg

 由于是第一次拿数据,redis当中并没有admin这个用户的信息,所以控制台输出以下信息:

dcabd39c633f45c5ab7ee0de1cb20fad.jpg

在此获得的数据是从数据库中拿到的,并且写入了redis,其结果如下:

a65f33520c2842e0ad8845b00945c475.jpg

当我们再次测试的时候,这时已经将admin这个用户的数据写入到了redis,所以控制台输出以下信息:

d88c499ad7f9413d97fbec780989a250.jpg

 写到这里,内容也就差不多了,大家也差不多可以实现这部分内容了,在此过程中,大家要注意给redis设置一个合适的key,最后能够看到这个命名就知道意思,别人也更好理解,还有就是redis的密码重置,可以暂时,也可以永久,如果只是短暂的,只需要启动redis服务,输入config set requirepass "密码"就可以,如果要长久的,就需要去配置文件当中改密码,然后重新启动就行了。

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐