Mybatis Cache(一)MybatisCache+Redis

news2025/2/24 16:06:36

前面提到了,使用mybatis cache,一般是结合redis使用。

一、demo

1、数据表
create table demo.t_address
(
    id           int auto_increment
        primary key,
    address_name varchar(200) null,
    address_code varchar(20)  null,
    address_type int          null
);

项目结构:

2、pom
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>plus-mybatis-cache</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.4</version>
        <relativePath/>
    </parent>


    <dependencies>

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

        <!--尽量不要同时导入mybatis 和 mybatis_plus,避免版本差异-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.5</version>
        </dependency>

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

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

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

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
    </dependencies>
</project>
3、配置文件
server.port=1112
server.servlet.context-path=/mybatisCacheDemo
#mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3308/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=wtyy
#mybatis
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
#打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 开启二级缓存
mybatis-plus.configuration.cache-enabled=true
#redis
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.password=
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.time-between-eviction-runs=30s
4、util
package com.pluscache.demo.util;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.Map;

@Component
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext ;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return ApplicationContextUtil.applicationContext.getBean(name);
    }

    public static <T> T getBean(String name, Class<T> clazz) {
        return applicationContext.getBean(name, clazz);
    }

    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
        return applicationContext.getBeansOfType(clazz);
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static <T extends Annotation> T getAnnotation(Object bean, Class<T> annotationClass) {
        T annotation = bean.getClass().getAnnotation(annotationClass);
        if (annotation == null) {
            annotation = AopUtils.getTargetClass(bean).getAnnotation(annotationClass);
        }
        return annotation;
    }

}
5、config
package com.pluscache.demo.config;

import com.pluscache.demo.util.ApplicationContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
//@Component
public class MybatisRedisCache implements Cache {

    /* * id是必须的带上的,这里的id会指定当前放入缓存的mapper的namespace
    * 如这里的id就是com.sample.dao.IEmployeeDao
    */
    private final String id;
    private  RedisTemplate redisTemplate;

    public MybatisRedisCache(final String id) {
       //获取redis实例
        //redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate");
        //指定key的序列化方式
        //redisTemplate.setKeySerializer(new StringRedisSerializer());
        //redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        this.id = id;
    }
    @Override
    public String getId() {
        return id;
    }

    @Override
    public void putObject(Object key, Object value) {
        this.getRedisTemplate();
        redisTemplate.opsForHash().put(id.toString(),key.toString(),value);
    }

    private void getRedisTemplate() {
        if (redisTemplate == null) {
            //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
            redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate");
        }
    }

    @Override
    public Object getObject(Object key) {
        this.getRedisTemplate();
        return redisTemplate.opsForHash().get(id.toString(),key.toString());
    }

    @Override
    public Object removeObject(Object key) {
        return null;
    }

    @Override
    public void clear() {
        this.getRedisTemplate();
        redisTemplate.delete(id.toString());
    }

    @Override
    public int getSize() {
        this.getRedisTemplate();
        return redisTemplate.opsForHash().size(id.toString()).intValue();
    }
}
6、dto
package com.pluscache.demo.dto;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

@Data
@TableName("t_address")
public class AddressDTO implements Serializable {
    private Integer id;
    private String addressName;
    private String addressCode;
    public Integer addressType;
}
7、dao
(1)repository

   可以省略,移到service中

package com.pluscache.demo.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pluscache.demo.dto.AddressDTO;
import com.pluscache.demo.mapper.AddressMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@Slf4j
public class AddressRepository {

    @Autowired
    private AddressMapper addressMapper;

    //plus新增
    public void insert(AddressDTO addressDTO) {
        addressMapper.insert(addressDTO);
    }

    //手动SQL新增
    public void save(AddressDTO addressDTO) {
        addressMapper.save(addressDTO);
    }

    public AddressDTO getById(Integer id) {
        LambdaQueryWrapper<AddressDTO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AddressDTO::getId, id);
        return addressMapper.selectOne(queryWrapper);
    }

    public List<AddressDTO> listByType(Integer type) {
        LambdaQueryWrapper<AddressDTO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AddressDTO::getAddressType, type);
        return addressMapper.selectList(queryWrapper);
    }

    public List<AddressDTO> listByTypeRecord(Integer type) {
        return addressMapper.listByTypeRecord(type);
    }
}
(2)mapper

   在这里做的缓存

package com.pluscache.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pluscache.demo.config.MybatisRedisCache;
import com.pluscache.demo.dto.AddressDTO;
import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@CacheNamespace(implementation = MybatisRedisCache.class, eviction = MybatisRedisCache.class)
public interface AddressMapper extends BaseMapper<AddressDTO> {

    void save(@Param("record") AddressDTO addressDTO);

    List<AddressDTO> listByTypeRecord(@Param("type") Integer type);
}
(3)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.pluscache.demo.mapper.AddressMapper">

    <cache-ref namespace="com.pluscache.demo.mapper.AddressMapper"/>

    <insert id="save">
        insert into t_address(address_name,
                              address_code,
                              address_type
                              ) values (#{record.addressName},
                                        #{record.addressCode},
                                        #{record.addressType})
    </insert>

    <select id="listByTypeRecord" resultType="com.pluscache.demo.dto.AddressDTO">
        select address_name,address_code from t_address where address_type =#{type}
    </select>

</mapper>
8、service
package com.pluscache.demo.service.impl;

import com.pluscache.demo.dto.AddressDTO;
import com.pluscache.demo.repository.AddressRepository;
import com.pluscache.demo.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("addressService")
public class AddressServiceImpl implements AddressService {

    @Autowired
    private AddressRepository addressRepository;

    @Override
    public void insert(AddressDTO addressDTO) {
        addressRepository.insert(addressDTO);
    }

    @Override
    public void save(AddressDTO addressDTO) {
        addressRepository.save(addressDTO);
    }

    @Override
    public AddressDTO getById(Integer id) {
        return addressRepository.getById(id);
    }

    @Override
    public List<AddressDTO> listByType(Integer type) {
        return addressRepository.listByType(type);
    }

    @Override
    public List<AddressDTO> listByTypeRecord(Integer type) {
        return addressRepository.listByTypeRecord(type);
    }
}
9、controller
package com.pluscache.demo.controller;

import com.pluscache.demo.dto.AddressDTO;
import com.pluscache.demo.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/address")
public class AddressController {

    @Autowired
    private AddressService addressService;

    @RequestMapping("/insert")
    public void insert(AddressDTO addressDTO) {
        addressService.insert(addressDTO);
    }

    @RequestMapping("/save")
    public void save(AddressDTO addressDTO) {
        addressService.save(addressDTO);
    }

    @RequestMapping("/getById")
    public AddressDTO getById(Integer id) {
        return addressService.getById(id);
    }


    @RequestMapping("/listByType")
    public List<AddressDTO> listByType(Integer type) {
        return addressService.listByType(type);
    }

    @RequestMapping("/listByTypeRecord")
    public List<AddressDTO> listByTypeRecord(Integer type) {
        return addressService.listByTypeRecord(type);
    }

}
10、启动类
package com.pluscache.demo;


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.pluscache.demo.mapper")
@SpringBootApplication
public class MybatisPlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);

    }
}
11、测试 

(1)新增数据

    新增了几条数据

(2)

二、缺点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1691222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java进阶学习笔记4——Static应用知识:代码块

代码块&#xff1a; 代码块是类的五大成员之一&#xff08;成员变量、构造器、方法、代码块、内部类&#xff09;。 Java类生命周期&#xff1a;加载、验证、准备、初始化、卸载。 代码块分为两种&#xff1a; 静态代码块&#xff1a; 格式&#xff1a;static {} 特点&…

Linux--网络通信(一)概述

网络通信概述 网络通信本质上是一种进程间通信&#xff0c;是位于网络中不同主机上的进程之间的通信&#xff0c;属于 IPC 的一种&#xff0c; 通常称为 socket IPC。所以网络通信是为了解决在网络环境中&#xff0c;不同主机上的应用程序之间的通信问题。 大概可以分为三个层…

物联网应用开发--STM32与机智云通信(ESP8266 Wi-Fi+手机APP+LED+蜂鸣器+SHT20温湿度传感器)

实现目标 1、熟悉机智云平台&#xff0c;会下载APP 2、熟悉新云平台创建产品&#xff0c;项目虚拟调试 3、掌握云平台生成MCU代码&#xff0c;并移植。机智云透传固件的下载 4、具体目标&#xff1a;&#xff08;1&#xff09;注册机智云平台&#xff1b;&#xff08;2&…

转行3年涨薪300%,我总结了一套产品经理快速入门指南!

想转行的产品小白&#xff0c;初期一定会遇到这个问题——我要如何 0 基础转行产品经理&#xff1f; 要想 0 基础快速转行产品经理&#xff0c;我通过个人实践总结了 5 个关键点&#xff0c;可以参考。 一、熟悉产品经理的工作全流程 转行的产品小白&#xff0c;首先要建立产…

mninst数据集图片下载

//不需要在官网下载&#xff0c;直接通过python代码&#xff0c;利用pytorch下载即可 from icecream import ic from torchvision import datasets from tqdm import tqdm import ostrain_data datasets.MNIST(root"./data/", trainTrue, downloadTrue) test_data …

VMware虚拟机桥接无线网卡上网(WIFI)

一、打开VM点击【编辑】-【虚拟网络编辑器】 二、点击【桥接模式】- 点击【自动设置】- 选择自己的无线网适配器 - 【确定】 三、开机之后会弹出提示连接网络&#xff0c;就能看见网络已经连上了

FastCopy

目录 背景: 简介&#xff1a; 原理: 下载地址: 工具的使用: 背景: 简介&#xff1a; FastCopy是一款速度非常快的拷贝软件&#xff0c;软件版本为5.7.1 Fastcopy是日本的最快的文件拷贝工具&#xff0c;磁盘间相互拷贝文件是司空见惯的事情&#xff0c;通常情况…

零一万物Yi-1.5开源,34B/9B/6B多尺寸,34B超Qwen1.5-72B

前言 近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;在各个领域展现出惊人的能力&#xff0c;为人们的生活和工作带来了巨大的改变。然而&#xff0c;大多数开源 LLM 的性能仍然无法与闭源模型相媲美&#xff0c;这限制了 LLM 在科研和商业领域的进一步应用。为了…

C# 利用Xejen框架源码,我们来开发一个基于Dapper技术的数据库通用的帮助访问类,通过Dapper的增删改查,可以访问Sqlite数据库

Dapper 是一个轻量级的对象关系映射&#xff08;ORM&#xff09;工具&#xff0c;适用于 .NET 平台。它由 Stack Overflow 团队开发&#xff0c;旨在提供简单、高效的数据访问功能。与其他重量级 ORM&#xff08;如 Entity Framework&#xff09;相比&#xff0c;Dapper 更加轻…

【算法例题】n元钱买n只鸡

题目描述&#xff1a;公鸡5元1只&#xff0c;母鸡3元1只&#xff0c;小鸡1元3只&#xff0c;问&#xff1a;n元钱买n只鸡&#xff0c;怎么买&#xff1f; 解题思路&#xff1a;这题要用枚举算法&#xff0c;枚举鸡的数量&#xff0c;代码如下&#xff1a; ​#include <bit…

博客系统(Servlet实现)

目录 1.准备工作 2.数据库设计 2.1表设计 2.2封装数据库操作代码 2.3创建 Blog 类 和 User 类 2.4创建 BlogDao 类和 UserDao 类 3.读取博客列表功能 3.1约定前后端交互接口 3.2实现服务器代码 3.3实现客户端代码 4.实现博客详情 4.1约定前后端交互接口 4.2实现服…

jmeter之线程组教程

一、线程组的作用 线程组是测试计划的子控件&#xff0c;也是取样器的父控件setup线程组&#xff0c;在所有线程组之前运行&#xff0c;类似于unittest框架中的SetUp函数&#xff0c;初始化环境teardown线程组&#xff0c;在所有线程组之后运行&#xff0c;类似于unittest中的…

如何在Windows 11和10上检查计算机的正常运行时间,这里有两种方法

序言 你的计算机的正常运行时间告诉你打开计算机已经有多长时间了。如果你需要这些信息进行故障排除或其他操作&#xff0c;那么很容易在Windows 11和Windows 10操作系统上找到你的正常运行时间。我们将向你展示图形和命令行方法。让我们开始吧。 使用任务管理器查找Windows正…

YoloV9实战与改进——专栏目录

摘要 &#x1f525;&#x1f680;本专栏教你如何嗨翻Yolov9&#xff01;&#x1f680;&#x1f525; &#x1f680;炸裂升级&#xff1a;嗨&#xff0c;小伙伴们&#xff01;这里有一波Yolov9的升级大招&#xff0c;带你领略最新论文的精华&#xff01;&#x1f4a5; 什么注意…

Star CCM+在电池热管理中SOC计算、充电Map调用、电池内阻调用的方法

前言 众所周知电池充电电流是随着电池温度与容量变化查表获得(形式见下表),其中电池的充电倍率(电流)是阶梯变化的,而内阻是线型变化的。因此为了仿真的准确定,需要在软件中实现数据的调用,计算电池的发热量。 电池内阻/充电倍率表 一 SOC计算 SOC的估算方法有开路电…

fpga 提高有什么进阶书推荐?

到FPGA中后期的时候就要开始接触&#xff0c;如&#xff1a;高速接口、光纤数字信号处理等项目实践了&#xff0c;那么我们可以读一些书进行提升&#xff0c;大家可以收藏下。 高速接口项目《嵌入式高速串行总线技术:基于FPGA实现与应用》作者&#xff1a;张锋 FPGA提升书籍推…

探索切片索引:列表反转的艺术

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;列表反转的挑战 二、切片索引的基本概念 三、切片索引实现列表反转 …

【微信小程序开发】小程序前后端交互--发送网络请求实战解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【计算机视觉(1)】

基于Python的OpenCV基础入门——图像的处理 计算机视觉简介OpenCV介绍图像的读取图像的显示图像窗口等待时间图像窗口的全部销毁图像的保存 图像的基本操作代码实现 计算机视觉简介 计算机视觉是人工智能 (AI) 的一个领域&#xff0c;是指让计算机和系统能够从图像、视频和其他…

Logstash笔记

目录​​​​​​​ 一、简介 二、单个输入和输出插件 三、多个输入和输出插件 四、pipeline结构 五、队列和数据弹性 六、内存队列 七、持久化队列 八、死信队列 (DLQ) 九、输入插件 1)、beats 2)、dead_letter_queue 3)、elasticsearch 4)、file 5)、redis 十、…