详解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 08 Redis
详解Redis瘦身指南
May 26 Redis
解析Redis Cluster原理
Jun 21 Redis
Redisson实现Redis分布式锁的几种方式
Aug 07 Redis
使用redis实现延迟通知功能(Redis过期键通知)
Sep 04 Redis
Jedis操作Redis实现模拟验证码发送功能
Sep 25 Redis
redis数据一致性的实现示例
Mar 18 Redis
Redis监控工具RedisInsight安装与使用
Mar 21 Redis
redis复制有可能碰到的问题汇总
Apr 03 Redis
muduo TcpServer模块源码分析
Apr 26 Redis
Redis批量生成数据的实现
Jun 05 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获取远程图片并把它保存到本地的代码
2008/04/07 PHP
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
PHP实现把数字ID转字母ID
2013/08/12 PHP
PHP中把对象转换为关联数组代码分享
2015/04/09 PHP
PHP SOCKET编程详解
2015/05/22 PHP
PHP根据session与cookie用户登录状态操作类的代码
2016/05/13 PHP
AlertBox 弹出层信息提示框效果实现步骤
2010/10/11 Javascript
ToolTips JQEURY插件之简洁小提示框效果
2011/11/19 Javascript
javascript自动给文本url地址增加链接的方法分享
2014/01/20 Javascript
Javascript基础教程之switch语句
2015/01/18 Javascript
JS和css实现检测移动设备方向的变化并判断横竖屏幕
2015/05/25 Javascript
jQuery插件windowScroll实现单屏滚动特效
2015/07/14 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
2015/08/25 Javascript
js实现符合国情的日期插件详解
2017/01/19 Javascript
Bootstrap table表格简单操作
2017/02/07 Javascript
Vue服务端渲染和Vue浏览器端渲染的性能对比(实例PK )
2017/03/31 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
2017/08/03 Javascript
vue 权限认证token的实现方法
2018/07/17 Javascript
Vuejs监听vuex中值的变化的方法示例
2018/12/02 Javascript
前端vue-cli项目中使用img图片和background背景图的几种方法
2019/11/13 Javascript
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
python分割文件的常用方法
2014/11/01 Python
Python使用爬虫猜密码
2016/02/19 Python
Python实现的下载网页源码功能示例
2017/06/13 Python
手把手教你python实现SVM算法
2017/12/27 Python
基于Python实现船舶的MMSI的获取(推荐)
2019/10/21 Python
Python字典生成式、集合生成式、生成器用法实例分析
2020/01/07 Python
django 文件上传功能的相关实例代码(简单易懂)
2020/01/22 Python
HTML5离线应用与客户端存储的实现
2018/05/03 HTML / CSS
美国快时尚彩妆品牌:Winky Lux(透明花瓣润唇膏)
2018/11/06 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
竞选班干部的演讲稿
2014/04/24 职场文书
离婚财产分隔协议书
2014/10/23 职场文书
拾金不昧感谢信范文
2015/01/21 职场文书
护士求职简历自我评价
2015/03/10 职场文书