详解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 相关文章推荐
在K8s上部署Redis集群的方法步骤
Apr 27 Redis
Redis IP地址的绑定的实现
May 08 Redis
redis实现共同好友的思路详解
May 26 Redis
Redis 彻底禁用RDB持久化操作
Jul 09 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
Redis读写分离搭建的完整步骤
Sep 14 Redis
Redis高可用集群redis-cluster详解
Mar 20 Redis
redis数据结构之压缩列表
Mar 21 Redis
redis复制有可能碰到的问题汇总
Apr 03 Redis
浅谈Redis缓冲区机制
Jun 05 Redis
Redis实现主从复制方式(Master&Slave)
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
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
在项目中寻找代码的坏命名
2012/07/14 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
Jquery 高亮显示文本中重要的关键字
2009/12/24 Javascript
jQuery的3种请求方式$.post,$.get,$.getJSON
2014/03/28 Javascript
JavaScript中逗号运算符介绍及使用示例
2015/03/13 Javascript
jquery处理页面弹出层查询数据等待操作实例
2015/03/25 Javascript
JavaScript forEach()遍历函数使用及介绍
2015/07/08 Javascript
浅谈JavaScript中小数和大整数的精度丢失
2016/05/31 Javascript
Node.js与Sails redis组件的使用教程
2017/02/14 Javascript
JS正则表达式验证中文字符
2017/05/08 Javascript
微信小程序之页面拦截器的示例代码
2017/09/07 Javascript
vuex的使用及持久化state的方式详解
2018/01/23 Javascript
JavaScript学习教程之cookie与webstorage
2019/06/23 Javascript
JavaScript使用localStorage存储数据
2019/09/25 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
2020/11/17 Vue.js
node使用async_hooks模块进行请求追踪
2021/01/28 Javascript
[51:17]Mski vs VGJ.S Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
使用WingPro 7 设置Python路径的方法
2019/07/24 Python
Python高级特性 切片 迭代解析
2019/08/23 Python
详解python中的闭包
2020/09/07 Python
PyQt5的QWebEngineView使用示例
2020/10/20 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
Python如何实现感知器的逻辑电路
2020/12/25 Python
美国性感女装网站:bebe
2017/03/04 全球购物
雅诗兰黛澳大利亚官网:Estée Lauder澳大利亚
2019/05/31 全球购物
全国道德模范事迹
2014/02/01 职场文书
2014年学校团委工作总结
2014/12/20 职场文书
CSS3 制作的图片滚动效果
2021/04/14 HTML / CSS
python实现三次密码验证的示例
2021/04/29 Python
Python 实现定积分与二重定积分的操作
2021/05/26 Python
pytorch中的 .view()函数的用法介绍
2022/03/17 Python
TV动画《史上最强大魔王转生为村民A》番宣CM公布
2022/04/01 日漫