Mybatis 二级缓存(使用Redis作为二级缓存)

news2024/11/28 1:48:29

上一篇我们介绍了mybatis中二级缓存的使用,本篇我们在此基础上介绍Mybatis中如何使用Redis作为二级缓存。

如果您对mybatis中二级缓存的使用不太了解,建议您先进行了解后再阅读本篇,可以参考:

Mybatis 二级缓存icon-default.png?t=N7T8https://blog.csdn.net/m1729339749/article/details/133376283

一、添加依赖

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-redis</artifactId>
    <version>1.0.0-beta2</version>
</dependency>

二、Redis配置

在resources目录下新建redis.properties配置文件

host=localhost
port=6379
connectionTimeout=2000
soTimeout=2000
password=horse
database=0
clientName=Mybatis_Cache

host:redis服务主机

port:redis服务端口

password:redis密码

三、创建实体类

在cn.horse.demo下创建UserInfo、UserInfoQuery类,另外需要特别注意缓存的对象类型必须实现Serializable接口

UserInfo类:

package cn.horse.demo;

import java.io.Serializable;

public class UserInfo implements Serializable {
    private static final long serialVersionUID = 9213975268411777481L;
    private Integer id;
    private String name;
    private Integer age;

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

    public Integer getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append('{');
        stringBuilder.append("id: " + this.id);
        stringBuilder.append(", ");
        stringBuilder.append("name: " + this.name);
        stringBuilder.append(", ");
        stringBuilder.append("age: " + this.age);
        stringBuilder.append('}');
        return stringBuilder.toString();
    }
}

UserInfoQuery类:

package cn.horse.demo;

public class UserInfoQuery {

    private Integer startAge;
    private Integer endAge;

    public void setStartAge(Integer startAge) {
        this.startAge = startAge;
    }

    public Integer getStartAge() {
        return startAge;
    }

    public void setEndAge(Integer endAge) {
        this.endAge = endAge;
    }

    public Integer getEndAge() {
        return endAge;
    }
}

四、创建映射器、Mapper配置

在cn.horse.demo下创建UserInfoMapper接口

UserInfoMapper接口:

package cn.horse.demo;

import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserInfoMapper {

    List<UserInfo> find(@Param("query") UserInfoQuery query);
}

在resources下创建cn/horse/demo目录,并在此目录下创建UserInfoMapper.xml配置文件

UserInfoMapper.xml配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.horse.demo.UserInfoMapper">

    <cache type="org.mybatis.caches.redis.RedisCache" />

    <resultMap id="userInfoMap" type="cn.horse.demo.UserInfo">
        <result column="ID" property="id" />
        <result column="USERNAME" property="name"/>
        <result column="AGE" property="age"/>
    </resultMap>

    <select id="find" parameterType="cn.horse.demo.UserInfoQuery" resultMap="userInfoMap">
        SELECT
            ID,
            USERNAME,
            AGE
        FROM T_USER
        <where>
            <if test="null != query.startAge">
                AND AGE &gt;= #{query.startAge}
            </if>
            <if test="null != query.endAge">
                AND AGE &lt;= #{query.endAge}
            </if>
        </where>
    </select>
</mapper>

注意:cache标签代表在此命名空间下使用二级缓存,type代表的是二级缓存的实现方式(这里使用的是org.mybatis.caches.redis.RedisCache)

五、引入配置文件

在resources下新建mybatis-config.xml配置文件,并引入UserInfoMapper映射器。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="logImpl" value="JDK_LOGGING"/>
    </settings>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="org.gjt.mm.mysql.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/demo?useUnicode=true&amp;useSSL=false&amp;characterEncoding=utf8&amp;allowMultiQueries=true"/>
                <property name="username" value="root"/>
                <property name="password" value="horse"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="cn.horse.demo.UserInfoMapper" />
    </mappers>
</configuration>

这里我们使用mapper引入映射器,只需要设置class属性为UserInfoMapper接口的全限类名。

六、启动程序

1、数据准备

这里我们直接使用脚本初始化数据库中的数据

-- 如果数据库不存在则创建数据库
CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARSET utf8;
-- 切换数据库
USE demo;
-- 创建用户表
CREATE TABLE IF NOT EXISTS T_USER(
  ID INT PRIMARY KEY,
  USERNAME VARCHAR(32) NOT NULL,
  AGE INT NOT NULL 
);
-- 插入用户数据
INSERT INTO T_USER(ID, USERNAME, AGE)
VALUES(1, '张三', 20),(2, '李四', 22),(3, '王五', 24);

创建了一个名称为demo的数据库;并在库里创建了名称为T_USER的用户表并向表中插入了数据

2、会话工具类

在cn.horse.demo包下新建SqlSessionUtils工具类

package cn.horse.demo;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;
import java.util.Objects;

public class SqlSessionUtils {

    private static final SqlSessionFactory sqlSessionFactory;
    static {
        // 读取mybatis配置文件
        InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
        // 根据配置创建SqlSession工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);
    }

    /**
     * 开启会话
     * @return
     */
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }

    /**
     * 关闭会话
     * @param sqlSession
     */
    public static void closeSession(SqlSession sqlSession) {
        if(Objects.nonNull(sqlSession)) {
            sqlSession.close();
        }
    }
}

3、JDK 日志系统配置

在resources的目录下新建logging.properties配置文件

handlers=java.util.logging.ConsoleHandler
.level=INFO

cn.horse.demo.level=FINER
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tT.%1$tL %4$s %3$s - %5$s%6$s%n

在cn.horse.demo下创建JdkLogConfig类

JdkLogConfig类:

package cn.horse.demo;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.LogManager;

public class JdkLogConfig {

    public JdkLogConfig() {
        try {
            InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("logging.properties");
            LogManager.getLogManager().readConfiguration(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

4、启动程序

package cn.horse.demo;

import org.apache.ibatis.session.SqlSession;

import java.util.List;
import java.util.function.Consumer;
import java.util.logging.Logger;

public class Main {

    private static final Logger LOGGER;

    static {
        // 引入JDK日志配置
        System.setProperty("java.util.logging.config.class", "cn.horse.demo.JdkLogConfig");
        LOGGER = Logger.getLogger("cn.horse.demo.Main");
    }

    public static void main(String[] args) throws InterruptedException {

        // 查询
        selectGreaterThan(20);
        // 查询
        selectGreaterThan(20);
    }

    private static void selectGreaterThan(Integer age) {
        LOGGER.finer("--------------- 查询 ----------------");
        execute((UserInfoMapper userInfoMapper) -> {
            UserInfoQuery query = new UserInfoQuery();
            query.setStartAge(age);
            List<UserInfo> userInfoList = userInfoMapper.find(query);
            for (UserInfo userInfo: userInfoList) {
                LOGGER.info(userInfo.toString());
            }
        });
    }

    private static void execute(Consumer<UserInfoMapper> function) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SqlSessionUtils.openSession();
            function.accept(sqlSession.getMapper(UserInfoMapper.class));
            sqlSession.commit();
        } finally {
            SqlSessionUtils.closeSession(sqlSession);
        }
    }
}

execute方法用于执行操作,方法中使用sqlSession.getMapper方法获取映射器对象,然后将映射器对象具体的执行操作委托给了Consumer对象。

执行后的结果如下:

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

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

相关文章

oracle分组合并数值带顺序

比如&#xff1a;有如下一张设备电子围栏位置坐标的表&#xff08;tb_equ_point&#xff09;。 equ_name:设备电子围栏名称 point_id:点位坐标id point_x:点位x坐标 point_y:点位y坐标。 附数据&#xff1a; INSERT INTO "tb_equ_point" ("EQU_NAME",…

数据结构题型11-顺序队列

#include <iostream> //引入头文件 using namespace std;typedef int Elemtype;#define Maxsize 5 #define ERROR 0 #define OK 1typedef struct {Elemtype data[Maxsize];int front, rear; }SqQueue;void InitQueue(SqQueue& Q) //初始化队列 {Q.rear Q.front…

使用代理IP进行安全高效的竞争情报收集,为企业赢得竞争优势

在激烈的市场竞争中&#xff0c;知己知彼方能百战百胜。竞争对手的信息对于企业来说至关重要&#xff0c;它提供了洞察竞争环境和市场的窗口。在这个信息时代&#xff0c;代理IP是一种实用的工具&#xff0c;可以帮助企业收集竞争对手的产品信息和营销活动数据&#xff0c;为企…

lv5 嵌入式开发-11 消息队列

掌握&#xff1a;消息队列机制、打开/创建消息队列、发送消息、接收消息 1 消息队列 消息队列是System V IPC对象的一种 消息队列由消息队列ID来唯一标识 消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等 消息队列可以按照类型来发送/接收消息 消…

Win10自带输入法怎么删除-Win10卸载微软输入法的方法

Win10自带输入法怎么删除&#xff1f;Win10系统自带输入法就是微软输入法&#xff0c;这个输入法满足了很多用户的输入需求。但是&#xff0c;有些用户想要使用其它的输入法&#xff0c;这时候就想删除掉微软输入法。下面小编给大家介绍最简单方便的卸载方法吧。 Win10卸载微软…

数据挖掘(1)概述

一、数据仓库和数据挖掘概述 1.1 数据仓库的产生 数据仓库与数据挖掘&#xff1a; 数据仓库和联机分析处理技术(存储)。数据挖掘&#xff1a;在大量的数据中心挖掘感兴趣的知识、规则、规律、模式、约束(分析)。数据仓库用于决策分析&#xff1a; 数据仓库&#xff1a;是在数…

在Qt中,怎么获取到在mainwindow.ui文件中添加的控件

2023年9月30日&#xff0c;周六晚上 假设我在mainwindow.ui中添加了一个名为textEdit的QTextEdit对象 在mainwindow.cpp中&#xff0c;可以通过ui对象来获取到这个控件

妙不可言的Python之旅----(一)

初识Python python的起源 1989年&#xff0c;为了打发圣诞节假期&#xff0c;Gudio van Rossum吉多 范罗苏姆&#xff08;龟叔&#xff09;决心开发一个新的解释程序&#xff08;Python雏形&#xff09; 1991年&#xff0c;第一个Python解释器诞生 Python这个名字&#xff…

怎么修改jupyter lab 的工作路径而不是直接再桌面路径打开

要修改Jupyter Lab的工作路径&#xff0c;你可以按照以下步骤操作&#xff1a; 打开终端或命令提示符窗口。 输入 jupyter lab --generate-config 命令来生成Jupyter Lab的配置文件。 找到生成的配置文件&#xff0c;通常会位于 ~/.jupyter/jupyter_notebook_config.py。 使…

C++ AB组辅导课

C AB组辅导课 蓝桥杯C AB组辅导课 第一讲 递归与递推 Acwing1、整数划分(递归)2、acwing92. 递归实现指数型枚举10凑算式(全排列)11李白打酒(全排列)12、棋牌总数(递归)13、剪邮票(递归)14、1050. 鸣人的影分身 (递归或动态规划(记忆化搜索))15、方格分割 &#xff08;dfs思维&…

蓝桥杯每日一题2023.9.30

蓝桥杯大赛历届真题 - C&C 大学 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 对于此题&#xff0c;首先想到了dfs进行一一找寻&#xff0c;注意每次不要将重复的算进去&#xff0c;故我们每次循环可以记录一个开始的位置&#xff0c;下一次到这个位置时&#xff0c;…

Git版本控制系统

概念&#xff1a; 一个免费的 开源 分布式源码仓库&#xff0c;帮助团队维护代码 个人使用 多人联机使用 git安装: 这里直接看大佬的安装 文章 很不错的 git 安装配置https://blog.csdn.net/mukes/article/details/115693833 安装完毕之后&#xff1a; 使用命名git -v查看…

腾讯云最新优惠活动汇总!来看看腾讯云最近都有哪些优惠活动!

腾讯云作为国内领先的云服务提供商之一&#xff0c;经常推出各种优惠活动来吸引用户&#xff0c;本文将为大家汇总腾讯云最新的优惠活动&#xff0c;希望能够帮助大家降低上云成本&#xff0c;提高用户上云体验。 一、腾讯云新用户优惠券【点击领取】 腾讯云针对新用户推出了…

mysql面试题6:MySQL索引的底层原理,是如何实现的?B+树和B树的区别?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL索引的底层原理,是如何实现的? MySQL索引的底层实现是通过B+树来实现的。B+树是一种多叉平衡查找树,它的特点是能够高效地支持数据的插入…

300多元耳机推荐哪个牌子好、性价比最高的开放式耳机推荐

随着蓝牙耳机产业的迅猛发展&#xff0c;目前最备受欢迎的蓝牙耳机类型之一就是开放式耳机。与传统的耳塞式蓝牙耳机相比&#xff0c;开放式耳机具备诸多优势&#xff0c;包括长时间佩戴的舒适性和安全性。开放式耳机不需要插入耳朵&#xff0c;也能提供音乐欣赏的体验&#xf…

【C++】多态面试题

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; C学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大…

【AIGC核心技术剖析】研究报告分享与汇总

AIGC研究报告 AI画画工具项目参考 AIGC&#xff08;Artificial General Intelligence Control&#xff09;技术是一种人工智能&#xff08;AI&#xff09;技术&#xff0c;旨在管理和控制人工智能系统的行为&#xff0c;以确保它们在执行任务时遵守一定的规则、伦理和价值观。A…

c进阶--指针进阶

&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c; 指针的简单回顾&#x1f33c;&#x1f33c;&#x1f33c;&#x…

助企上云新举措!移动云网盘服务平台正式上线

近日&#xff0c;移动云网盘服务平台&#xff08;DSP&#xff09;V1.0重磅发布。DSP作为移动云首个自研aPaaS平台&#xff0c;具备多存储节点纳管、高效文件管理、极速文件传输、多媒体数据处理、一体化运维支撑等功能特性&#xff0c;可满足文档管理、内容协作、云上会议、数据…

9.30消息队列

发送方&#xff1a; #include<myhead.h>//消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小int main(int argc, const char *argv[]) {//1.创建key值key_t key;if(…