Springboot+mp+redis implements caching

student table id sname cid

Class table cid cname

1. Query all classes and all information in the class and cache it in rdis (no paging required)

2. Stream stream to obtain the data of the second page (there are 2 pieces of data on each page)

pom.xml file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>redis1024</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redis1024</name>
    <description>redis1024</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!-- Automatically generate templates -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
                <dependency>
                    <groupId>org.freemarker</groupId>
                    <artifactId>freemarker</artifactId>
                </dependency>

                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.32</version>
                </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>9.3.7.v20160115</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.5</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties configuration file

#Set the index of reis
spring.redis.database=1
#Set the password to connect to redis
spring.redis.password=lyq
#Set the redis server
spring.redis.host=192.168.62.140
#The port number
spring.redis.port=6379
#Connection timeout (milliseconds)
spring.redis.timeout=1800000
#Maximum number of connections in the connection pool (use negative values to indicate no limit)
spring.redis.lettuce.pool.max-active=20
#Maximum blocking waiting time (negative number means no limit)
spring.redis.lettuce.pool.max-wait=-1
#Maximum idle connection in the connection pool
spring.redis.lettuce.pool.max-idle=5
#Minimum idle connection in the connection pool
spring.redis.lettuce.pool.min-idle=0


spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///test?serverTimezone=UTC & amp;useUnicode=true & amp;characterEncoding=utf-8 & amp;useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#Time configuration
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT + 8
spring.jackson.serialization.write-date-keys-as-timestamps=false
#logging.level.com.baomidou.ant.test.dao=debug
#mybatis-plus
# r_name rName setRName
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#mybatis-plus.configuration.log-impl=
mybatis-plus.mapper-locations=classpath:/mapper/*.xml
#Perform logical deletion and logical non-deletion operations, not deleted 0, deleted 1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1
RedisConfig configuration bean

package com.aaa.list1;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
/**
 * @author
 * @create Li Yaoqi
 */
@Configuration
public class RedisConfig {
//The return object of this method is handed over to the spring container management
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        //Specify the domain to be serialized, field, get and set, and the modifier range, ANY includes private and public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // Specify the type of serialized input. The class must be non-final modified. Final modified classes, such as String, Integer, etc., will throw exceptions.
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //Key serialization method
        template.setKeySerializer(redisSerializer);
        //value serialization
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap serialization
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
    /**
     * Caching processing
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//Solve the problem of query cache conversion exception
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
// Configure serialization (to solve the problem of garbled characters), expiration time is 600 seconds
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(3600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

Controller layer

package com.aaa.controller;

import com.aaa.entity.Studentclass;
import com.aaa.service.IStudentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * Front-end controller
 *</p>
 *
 * @author lyq
 * @since 2023-10-25
 */
@RestController
@RequestMapping("/student")
public class StudentController {

    @Resource
    private IStudentService studentService;

// @RequestMapping("/all")
// public List<Student> findAll1(){
// List<Student> list = studentService.All();
// return list;
// }

    @GetMapping("/{index}/{size}")
    public List<Object> findAll(@PathVariable(value = "index") Integer index,
                                @PathVariable(value = "size") Integer size){
        List<Studentclass> list = studentService.All();
        List<Object> objects = studentService.All1(index,size);
        return objects;
    }

}

service

package com.aaa.service;

import com.aaa.entity.Student;
import com.aaa.entity.Studentclass;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 * Service category
 *</p>
 *
 * @author lyq
 * @since 2023-10-25
 */
public interface IStudentService extends IService<Student> {


// @Cacheable(value = "depts",key = "#root.methodName")
    List<Studentclass> All();
    List<Object> All1(Integer index, Integer size);




}

package com.aaa.service.impl;

import com.aaa.entity.Student;
import com.aaa.entity.Studentclass;
import com.aaa.mapper.StudentMapper;
import com.aaa.service.IStudentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * Service implementation class
 *</p>
 *
 * @author lyq
 * @since 2023-10-25
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {
    @Resource
    private StudentMapper studentMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    @Cacheable(value = "depts", key = "'student'")
    public List<Studentclass> All() {
        List<Studentclass> users = studentMapper.all();
        //Save data into redis
        return users;
        //return
    }
    @Override
    public List<Object> All1(Integer index, Integer size) {
        int i = (index - 1) * size;
        List<Object> o = (List<Object>) redisTemplate.opsForValue().get("depts::student");
        //o.stream() //This method converts an object into a stream (Stream) for streaming operations. A stream is a special data structure that allows you to process data in a linear manner, as if you were processing a data stream.
        // .skip(i) // Skip i elements
        // .limit(size) // Get the first size elements
        // .collect(Collectors.toList()); // Collect into list
        List<Object> collect = o.stream().skip(i).limit(size).collect(Collectors.toList());
        return collect;
    }
}

mapper

package com.aaa.mapper;

import com.aaa.entity.Student;
import com.aaa.entity.Studentclass;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

/**
 * <p>
 * Mapper interface
 *</p>
 *
 * @author lyq
 * @since 2023-10-25
 */
public interface StudentMapper extends BaseMapper<Student> {

    List<Studentclass> all();

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aaa.mapper.StudentMapper">

    <resultMap id="Studentall" type="com.aaa.entity.Studentclass" autoMapping="true">
        <id property="cid" column="cid"></id>
    <collection property="student" ofType="com.aaa.entity.Student" autoMapping="true">
            <id column="id" property="id"></id>
    </collection>
    </resultMap>

    <select id="all" resultMap="Studentall">
        select * from studentclass s
            join student s1 on s.cid = s1.cid
    </select>

</mapper>