详解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 12 Redis
基于Redis延迟队列的实现代码
May 13 Redis
压缩Redis里的字符串大对象操作
Jun 23 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
为什么RedisCluster设计成16384个槽
Sep 25 Redis
详解Redis在SpringBoot工程中的综合应用
Oct 16 Redis
redis击穿 雪崩 穿透超详细解决方案梳理
Mar 17 Redis
高并发下Redis如何保持数据一致性(避免读后写)
Mar 18 Redis
源码分析Redis中 set 和 sorted set 的使用方法
Mar 22 Redis
使用Redis做预定库存缓存功能
Apr 02 Redis
关于Redis的主从复制及哨兵问题
Jun 16 Redis
利用Redis实现点赞功能的示例代码
Jun 28 Redis
Redis三种集群模式详解
浅谈Redis的keys命令到底有多慢
基于Redis结合SpringBoot的秒杀案例详解
Jedis操作Redis实现模拟验证码发送功能
Sep 25 #Redis
为什么RedisCluster设计成16384个槽
使用redis生成唯一编号及原理示例详解
Sep 15 #Redis
Redis读写分离搭建的完整步骤
Sep 14 #Redis
You might like
用cookies来跟踪识别用户
2006/10/09 PHP
删除html标签得到纯文本可处理嵌套的标签
2014/04/28 PHP
ThinkPHP调试模式与日志记录概述
2014/08/22 PHP
PHP实现中文圆形印章特效
2015/06/19 PHP
php利用gd库为图片添加水印
2016/11/09 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
2020/02/21 PHP
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
15款jQuery分布引导插件分享
2015/02/04 Javascript
JavaScript从数组中删除指定值元素的方法
2015/03/18 Javascript
JavaScript利用HTML DOM进行文档操作的方法
2016/03/28 Javascript
artDialog+plupload实现多文件上传
2016/07/19 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
用vue写一个仿简书的轮播图的示例代码
2018/03/13 Javascript
详解Vue 多级组件透传新方法provide/inject
2018/05/09 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
2018/08/31 Javascript
JavaScript实现shuffle数组洗牌操作示例
2019/01/03 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
vue+ESLint 配置保存 自动格式化代码
2020/03/17 Javascript
Python使用gensim计算文档相似性
2016/04/10 Python
Python三级目录展示的实现方法
2016/09/28 Python
Python Socket传输文件示例
2017/01/16 Python
python3.6连接MySQL和表的创建与删除实例代码
2017/12/28 Python
Python实现按照指定要求逆序输出一个数字的方法
2018/04/19 Python
python字符串与url编码的转换实例
2018/05/10 Python
基于python实现百度翻译功能
2019/05/09 Python
关于python3中setup.py小概念解析
2019/08/22 Python
Python Unittest原理及基本使用方法
2020/11/06 Python
IE9下html5初试小刀
2010/09/21 HTML / CSS
如何用Lucene索引数据库
2016/02/23 面试题
简述数组与指针的区别
2014/01/02 面试题
string = null 和string = ''的区别
2013/04/28 面试题
飞利信loadrunner和软件测试笔试题
2012/09/22 面试题
教育学习自我评价
2014/02/03 职场文书
《一本男孩子必读的书》教学反思
2014/02/19 职场文书
中学生民族团结演讲稿
2014/08/27 职场文书
民主评议党员个人总结
2015/02/13 职场文书