栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

07-Redis在SpringBoot工程中的综合应用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

07-Redis在SpringBoot工程中的综合应用

RedisTemplate应用 简介

RedisTemplate为SpringBoot工程中操作redis数据库的一个Java对象,此对象封装了对redis的一些基本操作。

准备工作

添加依赖


        
            
                org.springframework.boot
                spring-boot-dependencies
                2.3.2.RELEASE
                import
                pom
            
        
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
准备工作

第一步:创建工程配置文件application.yml,其内容如下:

spring:
  redis: # redis-cli -c -h 192.168.126.129 -p 8010
    host: 192.168.126.129
    port: 6379
  datasource: #mysql连接
    url: jdbc:mysql:///blog?serverTimezone=Asia/Shanghai&characterEncoding=utf8
    username: root
    password: 123456

#日志配置
logging:
  level:
    com.jt: debug

第二步:创建工程启动类,例如:

package com.jt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class,args);
    }
}
快速入门实现 StringRedisTemplate 应用

StringRedisTemplate 是一个专门用于操作redis字符串类型数据的一个对象,其应用方式如下:

@SpringBootTest
public class StringRedisTemplateTests {
    
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    @Test
    void testHashOper01(){
        //1.获取hash操作对象
        HashOperations vo =stringRedisTemplate.opsForHash();

        //2.读写redis数据
        //2.1存储一个对象
        vo.put("user","id","100");
        vo.put("user","username","tony");
        vo.put("user","status","1");
        //2.2获取一个对象
        Object status = vo.get("user","status" );
        System.out.println(status);
        List user = vo.values("user");
        System.out.println(user);
    }
    
    @Test
    void testStringOper02() throws JsonProcessingException {
        //1.获取字符串操作对象
        ValueOperations vo = stringRedisTemplate.opsForValue();

        //2.读写redis中的数据
        Map map = new HashMap<>();
        map.put("id","100");
        map.put("title","StringRedisTemplate");
        String jsonStr = new ObjectMapper().writevalueAsString(map);
        vo.set("blog",jsonStr);
         jsonStr = vo.get("blog");
        System.out.println(jsonStr);
        map = new ObjectMapper().readValue(jsonStr,Map.class);
        System.out.println(map);
    }
    
    @Test
    void testStringOper01(){
        //1.获取字符串操作对象
        ValueOperations vo = stringRedisTemplate.opsForValue();

        //2.读写redis中的数据
        vo.set("xx","100");
        vo.increment("xx");
        vo.set("yy","200",1, TimeUnit.SECONDS);
        String xx = vo.get("xx");
        String yy = vo.get("yy");
        System.out.println("xx:"+xx);
        System.out.println("yy:"+yy);
    }
    
    @Test
    void testGetConnection(){
        RedisConnection connection =
        stringRedisTemplate.getConnectionFactory().getConnection();
        String ping = connection.ping();
        System.out.println(ping);
    }
}
 
RedisTemplate 应用 

RedisTemplate是一个专门用于实现对远端redis中复杂数据的操作的对应,应用案例如下:

@SpringBootTest
public class RedisTemplateTests {
    //这个对象在springboot工程的RedisAutoConfiguration类中已经做了配置
    //次对象在基于redis存取数据时

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void testSetOper01(){
        //1.获取操作set类型数据的操作对象
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        SetOperations so = redisTemplate.opsForSet();
        //2.读写redis数据set类型数据
        so.add("set1","a","b","c","c");
        Set set1 = so.members("set1");

        System.out.println(set1);

    }


    @Test
    void testListOper01(){
        //1.获取操作List类型数据的操作对象
        ListOperations lo = redisTemplate.opsForList();
        //2.读写redis数据hash类型数据

        lo.leftPush("list1","A");
        lo.leftPushAll("list1","B","C","D");
        lo.leftPop("list1");
        List list = lo.range("list1", 0, -1);
        System.out.println(list);
    }


    @Test
    void testHashOper01(){
        //1.获取操作hash类型数据的操作对象
        HashOperations ho = redisTemplate.opsForHash();
        //2.读写redis数据hash类型数据
        Map map = new HashMap<>();
        map.put("id",100);
        map.put("title","spring boot");
        //直接存储一个map
        ho.putAll("blog",map);// hash 存储。序列化
        //存储单个字段,值
        ho.put("blog","content","spring boot redis");
        //取blog对象中id属性的值
        Object o = ho.get("blog", "id");
        System.out.println(o);
        //获取整个blog对象所有的属性和值
        Map blog = ho.entries("blog");// 反序列化
        System.out.println(blog);

    }

    @Test
    void testStringOper01(){
        //自己指定key/value序列化方式
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        ValueOperations vo = redisTemplate.opsForValue();
        //key和value默认会采用JDK的序列化方式进行存储
        vo.set("token", UUID.randomUUID().toString());
        Object token = vo.get("token");
        System.out.println(token);
    }


    @Test
    void testGetConnection(){
        RedisConnection connection =redisTemplate.getConnectionFactory().getConnection();
        String ping = connection.ping();
        System.out.println(ping);
    }

}
定制RedisTemplate对象(拓展)

对于系统默认的RedisTemplate默认采用的是JDK的序列化机制,假如我们不希望实用JDK的序列化,可以采用的定制RedisTemplate,并采用自己指定的的序列化方式,例如:

package com.jt.redis.config;
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //1.构建RedisTemplate对象
        RedisTemplate redisTemplate=new RedisTemplate<>();
        //2.设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //3.定义序列化方式(在这里选择jackson)
        Jackson2JsonRedisSerializer redisSerializer= new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper=new ObjectMapper();
        //设置要序列化的域(属性)
        //any表示任意级别访问修饰符修饰的属性 private,public,protected
        objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
        //启动输入域检查(类不能是final修饰的)
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypevalidator(),
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY);
        redisSerializer.setObjectMapper(objectMapper);
        //4.设置RedisTemplate的序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(redisSerializer);
        //spring规范中假如修改bean对象的默认特性,建议调用一下afterPropertiesSet()
        redisTemplate.afterPropertiesSet();
       return redisTemplate;
    }
}

创建Blog对象,然后基于RedisTemplate进行序列化实践,Blog代码如下

package com.jt.redis.pojo;

import java.io.Serializable;

public class Blog implements Serializable {//{"id":10,"title":"redis"}
    private static final long serialVersionUID = -6721670401642138021L;
    private Integer id;
    private String title;
    public Blog(){
        System.out.println("Blog()");
    }
    public Blog(Integer id,String title){
        this.id=id;
        this.title=title;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    @Override
    public String toString() {
        return "Blog{" +
                "id=" + id +
                ", title='" + title + ''' +
                '}';
    }
}

在RedisTemplateTests类中添加如下单元测试方法,进行测试,例如:

@Test
void testJsonOper() throws JsonProcessingException {
    ValueOperations valueOperations = redisTemplate.opsForValue();
    Blog blog=new Blog(10,"study redis");
    valueOperations.set("blog",blog);//序列化
    blog=(Blog)valueOperations.get("blog");//反序列化
    System.out.println("blog="+blog);
}
业务描述

从一个博客数据库中查询所有的文章标签,然后存储到缓存(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
    mysql-connector-java



    com.baomidou
    mybatis-plus-boot-starter
    3.4.2

添加数据库访问配置

在项目的配置文件(例如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;
    
    @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 {
}

创建单元测试类,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 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 {
    
    List 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 selectTags() {
        //1.从redis查询Tag信息,redis有则直接返回
        ValueOperations> valueOperations =
        redisTemplate.opsForValue();
        List 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 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 doSelectTags(){
      return  tagService.selectTags());//1.redis,2.mysql
    }
}

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

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号