SpringBoot开发中如何缓存数据, 减少数据库的访问频率?

一:自定义是否开启缓存

方法一:

在不同环境的配置文件中如application-dev.yml、application-test.yml、application-prod.yml,修改 spring.cache.type = none;

复制代码
spring:
  cache:
  	type: none	

方法二:

自定义配置

application.yml:

复制代码
## 开启数据缓存
caching:
  enabled: true

com.scaffold.test.config.CacheConfig

缓存配置文件

复制代码
@Configuration
@EnableCaching
//配置文件读取是否启用此配置
@ConditionalOnProperty(prefix = "caching", name = "enabled", havingValue = "true")
public class CacheConfig {

}

二:simpleCacheManage

simpleCacheManage 基于ConcurrentHashMap 实现,不依赖其他库,如果增加了注解@EnableCaching,默认开启缓存,可以通过设置cache-names限制缓存列表

1.设置缓存列表

application.yml

复制代码
spring:
  cache:
  	type: simple
  	cache-names: cache1,cache2

2.添加maven依赖:

复制代码
<!-- cache 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

3.使用注解

注意:所有的注解是加到实现类serviceImpl方法上的

|-------------|-------------------------------------------------------------|
| 注解 | 描述 |
| @Cacheable | 在方法执行前 Spring 先查看缓存中是否有数据,若有,则直接返回缓存数据;若无数据,调用方法将方法返回值放入缓存中 |
| @CachePut | 无论怎样,都会将方法的返回值放到缓存中。 |
| @CacheEvict | 将一条或多条数据从缓存中删除 |
| @Caching | 可以通过 @Caching 注解组合多个注解策略在一个方法 |

@Cacheable、@CachePut、@CacheEvict 都有 value 属性,指定的是要使用的缓存名称;key 属性指定的是数据在缓存中存储的键

4.代码实现:

4.1配置类

复制代码
package com.scaffold.test.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

/**
 * 缓存配置文件
 * 配置文件读取是否启用此配置
 * @author alex
 */
@Configuration
@EnableCaching
@ConditionalOnProperty(prefix = "caching", name = "enabled", havingValue = "true")
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("cacheData");
    }
  }

4.2实体类

复制代码
package com.scaffold.test.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;

/**
 * @author alex wong
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Student implements Serializable {

    private static final long serialVersionUID=1L;

    private int id;

    private String name;

    private Integer age;

}

4.3service层

复制代码
package com.scaffold.test.service;

import com.scaffold.test.entity.Student;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author alex wong
 */
public interface StudentService extends IService<Student> {

    List<Student> findAll();

    Student findStudent(Student student);

    Student testStudent(String text);

    void deleteStudent(Student student);

    void saveStudent(Student student);

}

4.4service实现类

复制代码
package com.scaffold.test.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scaffold.test.entity.Student;
import com.scaffold.test.mapper.StudentMapper;
import com.scaffold.test.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author alex wong
 */

@Slf4j
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Resource
    private StudentMapper studentMapper;

    @Override
    @Cacheable(value = "cacheData")
    public List<Student> findAll(){
        return studentMapper.selectAll();
    }

    /**
     * 缓存查询数据
     * @Cacheable 缓存数据到缓存 student 中
     * 其中缓存名称为 student 数据的 key 是 student 的 id
     * @param student s
     * @return
     */
    @Override
    @Cacheable(value = "cacheData", key = "#student.id")
    public Student findStudent(Student student) {
        log.warn("增加了student为{}的数据缓存", student);
        int id = student.getId();
        if(id == 0){
            return null;
        }
        return studentMapper.findStudent(student);
    }

    /**
     * 删除缓存
     * @CacheEvict 从缓存 student 中删除
     * 其中缓存名称为 student 数据的 key 是 student 的 id
     * @param student s
     */
    @Override
    @CacheEvict(value = "cacheData", key = "#student.id")
    public void deleteStudent(Student student) {
        log.warn("删除了student为{}的数据缓存", student);
    }

    /**
     * @CachePut 缓存新增的或更新的数据到缓存
     * 其中缓存名称为 student 数据的 key 是 student 的 id
     * @param student
     */
    @Override
    @CachePut(value = "cacheData", key = "#student.id")
    public void saveStudent(Student student) {
        log.warn("保存了id、key 为{}的数据缓存", student);
        studentMapper.insertStudent(student);
    }


    @Override
    @Cacheable(value = "cacheData", key = "#text")
    public Student testStudent(String text) {
        System.out.println("test" + text);
        Student student = new Student();
        student.setName(text);
        return student;
    }
}

4.5dao层接口:

复制代码
package com.scaffold.test.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.scaffold.test.entity.Student;

import java.util.List;

/**
 * <p>
 * Mapper 接口
 * </p>
 *
 * @author alex wong
 */
public interface StudentMapper extends BaseMapper<Student> {

    List<Student> selectAll();

    Student findStudent(Student student);

    int insertStudent(Student student);
}

4.6Mapper。xml文件

复制代码
<?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.scaffold.test.mapper.StudentMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.scaffold.test.entity.Student">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="age" property="age"/>
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id,
        name, age
    </sql>

    <sql id="Where_Condition">
        <where>
            <if test="id != null and id != ''">
                id=#{id}
            </if>
            <if test="name != null and name != ''">
                and name=#{name}
            </if>
            <if test="age != null and age != ''">
                and age=#{age}
            </if>
        </where>
    </sql>

    <insert id="insertStudent">
        insert student
        (id, name, age)
        values
        (#{id}, #{name}, #{age})
    </insert>

    <select id="selectAll" resultMap="BaseResultMap">
        select * from student
    </select>

    <select id="findStudent" resultType="com.scaffold.test.entity.Student">
        select * from student
        <include refid="Where_Condition"></include>
    </select>
</mapper>

4.7sql

复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '1', 2323);
INSERT INTO `student` VALUES (2, '2', 2323);
INSERT INTO `student` VALUES (3, '3', 2323);

SET FOREIGN_KEY_CHECKS = 1;

4.8Controller层

复制代码
package com.scaffold.test.controller;


import com.scaffold.test.entity.Student;
import com.scaffold.test.service.StudentService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author alex wong
 */
@RestController
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("list")
    public List<Student> getAll(){
        return studentService.findAll();
    }

    @GetMapping("add")
    public void addStudent(Student student){
        studentService.saveStudent(student);
    }

    @GetMapping("find")
    public Student findStudent(Student student){
        return studentService.findStudent(student);
    }

    @GetMapping("delete")
    public void deleteStudent(Student student){
        studentService.deleteStudent(student);
    }

    @GetMapping("test")
    public Student test(@RequestParam String text){
        return studentService.testStudent(text);
    }
}
相关推荐
zzb15803 小时前
RAG from Scratch-优化-query
java·数据库·人工智能·后端·spring·mybatis
一只鹿鹿鹿4 小时前
信息安全等级保护安全建设防护解决方案(总体资料)
运维·开发语言·数据库·面试·职场和发展
堕2744 小时前
MySQL数据库《基础篇--数据库索引(2)》
数据库·mysql
wei_shuo4 小时前
数据库优化器进化论:金仓如何用智能下推把查询时间从秒级打到毫秒级
数据库·kingbase·金仓
wuqingshun3141594 小时前
如何停止一个正在退出的线程
java·开发语言·jvm
雷工笔记4 小时前
Navicat Premium 17 软件安装记录
数据库
wenlonglanying4 小时前
Ubuntu 系统下安装 Nginx
数据库·nginx·ubuntu
数据库小组5 小时前
10 分钟搞定!Docker 一键部署 NineData 社区版
数据库·docker·容器·database·数据库管理工具·ninedata·迁移工具
Barkamin5 小时前
队列的实现(Java)
java·开发语言
爬山算法5 小时前
MongoDB(38)如何使用聚合进行投影?
数据库·mongodb