详解Redis在SpringBoot工程中的综合应用


Posted in Redis onOctober 16, 2021

业务描述

从一个博客数据库中查询所有的文章标签,然后存储到缓存(Cache),后续查询时可从缓存获取。提高其查询性能。

准备工作

初始化数据

初始化数据库中数据,SQL脚本如下:

DROP DATABASE IF EXISTS `blog`;
CREATE DATABASE `blog` DEFAULT character set utf8mb4;
SET names utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
USE `blog`;

CREATE TABLE `tb_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) NOT NULL COMMENT 'data_id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tb_tag';

insert into `tb_tag` values (null,"mysql"),(null,"redis");

添加项目依赖

在jt-template工程的原有依赖基础上添加mysql数据库访问依赖,例如:

<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>

添加数据库访问配置

在项目的配置文件(例如application.yml)中添加数据库访问配置,例如:

spring:
  datasource:
    url: jdbc:mysql:///blog?serverTimezone=Asia/Shanghai&characterEncoding=utf8
    username: root
    password: root

业务逻辑代码设计及实现

Domain对象设计

创建一个Tag类,基于此类型的对象存储Tag(标签信息),代码如下:

package com.jt.blog.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;

/**
 * 标签类的设计
 */
@TableName("tb_tag")
public class Tag implements Serializable {
    private static final long serialVersionUID = 4504013456197711455L;
    /**标签id*/
    @TableId(type = IdType.AUTO)
    private Long id;
    /**标签名*/
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Tag{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Dao 逻辑对象设计

创建Tag信息的数据访问接口,代码如下:

package com.jt.blog.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.blog.domain.Tag;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface TagMapper
        extends BaseMapper<Tag> {
}

创建单元测试类,TagMapper中的相关方法进行单元测试,例如:

package com.jt.blog.dao;

import com.jt.blog.domain.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class TagMapperTests {
    @Autowired
    private TagMapper tagMapper;
    @Test
    void testSelectList(){
        List<Tag> tags =
        tagMapper.selectList(null);
        for(Tag t:tags){
            System.out.println(t);
            //System.out.println(t.getId()+"/"+t.getName());
        }
    }
}

Service 逻辑对象设计

设计TagService接口及实现类,定义Tag(标签)业务逻辑。
第一步:定义TagService接口,代码如下:

package com.jt.blog.service;
import com.jt.blog.domain.Tag;
import java.util.List;
public interface TagService {
    /**
     * 查询所有的标签
     * @return
     */
    List<Tag> selectTags();
}

第二步:定义TagServiceImpl类,代码如下:

package com.jt.blog.service.impl;

import com.jt.blog.dao.TagMapper;
import com.jt.blog.domain.Tag;
import com.jt.blog.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class TagServiceImpl implements TagService {
    //RedisAutoConfiguration 类中做的RedisTemplate的配置
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TagMapper tagMapper;
    @Override
    public List<Tag> selectTags() {
        //1.从redis查询Tag信息,redis有则直接返回
        ValueOperations<String,List<Tag>> valueOperations =
        redisTemplate.opsForValue();
        List<Tag> tags=valueOperations.get("tags");
        if(tags!=null&&!tags.isEmpty())return tags;
        //2.从redis没有获取tag信息,查询mysql
        tags = tagMapper.selectList(null);
        //3.将从mysql查询到tag信息存储到redis
        valueOperations.set("tags", tags);
        //4.返回查询结果
        return tags;
    }
}

说明,假如将List存储到redis,此时Tag必须实现Serializable接口。

第三步:定义TagServiceTests单元测试类并进行单元测试,代码如下:

package com.jt.blog.service;

import com.jt.blog.domain.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class TagServiceTests {
    @Autowired
    private TagService tagService;
    
    @Test
    void testSelectTags(){
        List<Tag> tags=
        tagService.selectTags();
        System.out.println(tags);
    }
}

Controller逻辑对象设计

创建Tag控制逻辑对象,用于处理请求和响应逻辑,代码如下:

package com.jt.blog.controller;

import com.jt.blog.domain.Tag;
import com.jt.blog.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/tag")
public class TagController {
    @Autowired
    private TagService tagService;
    
    @GetMapping
    public  List<Tag> doSelectTags(){
      return  tagService.selectTags());//1.redis,2.mysql
    }
}

启动服务,打开浏览器进行访问测试。同时思考,我们是否可以在这个层加一个本地cache。

总结(Summary)

本章节重点是学习项目中缓存(Cache)的一种应用思想。

到此这篇关于Redis在SpringBoot工程中的综合应用的文章就介绍到这了,更多相关Redis在SpringBoot综合应用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
Redis安装启动及常见数据类型
Apr 14 Redis
浅谈Redis在直播场景的实践方案
Apr 27 Redis
redis 查看所有的key方式
May 07 Redis
详解redis分布式锁的这些坑
May 19 Redis
redis实现排行榜功能
May 24 Redis
浅谈Redis的几个过期策略
May 27 Redis
redis中lua脚本使用教程
Nov 01 Redis
Redis安装使用RedisJSON模块的方法
Mar 23 Redis
 Redis 串行生成顺序编码的方法实现
Apr 03 Redis
Redis keys命令的具体使用
Jun 05 Redis
浅谈Redis变慢的原因及排查方法
Jun 21 Redis
Redis过期数据是否会被立马删除
Jul 23 Redis
Redis三种集群模式详解
浅谈Redis的keys命令到底有多慢
基于Redis结合SpringBoot的秒杀案例详解
Jedis操作Redis实现模拟验证码发送功能
Sep 25 #Redis
为什么RedisCluster设计成16384个槽
使用redis生成唯一编号及原理示例详解
Sep 15 #Redis
Redis读写分离搭建的完整步骤
Sep 14 #Redis
You might like
PHP4 与 MySQL 交互使用
2006/10/09 PHP
PHP多线程抓取网页实现代码
2010/07/22 PHP
PHP的拦截器实例分析
2014/11/03 PHP
PHP使用glob函数遍历目录或文件夹的方法
2014/12/16 PHP
PHP中调用C/C++制作的动态链接库的教程
2016/03/10 PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
2019/05/29 PHP
PHP Cli 模式设置进程名称的方法
2019/06/12 PHP
node.js中的fs.link方法使用说明
2014/12/15 Javascript
跟我学习javascript的prototype使用注意事项
2015/11/17 Javascript
每天一篇javascript学习小结(属性定义方法)
2015/11/19 Javascript
Javascript实现的SHA-256加密算法完整实例
2016/02/02 Javascript
jQuery实现查找最近父节点的方法
2016/06/23 Javascript
js验证真实姓名与身份证号,手机号的简单实例
2016/07/18 Javascript
Vuejs第十一篇组件之slot内容分发实例详解
2016/09/09 Javascript
canvas压缩图片转换成base64格式输出文件流
2017/03/09 Javascript
js原生方法被覆盖,从新赋值原生的方法
2018/01/02 Javascript
移动端底部导航固定配合vue-router实现组件切换功能
2019/06/13 Javascript
JavaScript:ES2019 的新特性(译)
2019/08/08 Javascript
uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能
2019/11/12 Javascript
vue 使用外部JS与调用原生API操作示例
2019/12/02 Javascript
解决vue-router 嵌套路由没反应的问题
2020/09/22 Javascript
[01:18]一目了然!DOTA2DotA快捷操作对比第一弹
2014/07/01 DOTA
用Python输出一个杨辉三角的例子
2014/06/13 Python
利用Python+Java调用Shell脚本时的死锁陷阱详解
2018/01/24 Python
python实现冒泡排序算法的两种方法
2018/03/10 Python
使用Python读取安卓手机的屏幕分辨率方法
2018/03/31 Python
破解安装Pycharm的方法
2018/10/19 Python
django 数据库连接模块解析及简单长连接改造方法
2019/08/29 Python
如何利用python给图片添加半透明水印
2019/09/06 Python
受欢迎的大学生自我评价
2013/12/05 职场文书
给交警的表扬信
2014/01/12 职场文书
护士毕业自我鉴定
2014/02/07 职场文书
便利店促销方案
2014/02/20 职场文书
建筑投标担保书
2014/05/20 职场文书
学校2014重阳节活动策划方案
2014/09/16 职场文书
MySQL数据库10秒内插入百万条数据的实现
2021/11/01 MySQL