当前位置:首页 » 《我的小黑屋》 » 正文

Java-13 深入浅出 MyBatis - 二级缓存整合Redis 代码测试 与 原理探究 源码分析

1 人参与  2024年12月30日 12:01  分类 : 《我的小黑屋》  评论

点击全文阅读


点一下关注吧!!!非常感谢!!持续更新!!!

大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html

在这里插入图片描述

目前已经更新到了:

MyBatis(正在更新)

二级缓存整合 Redis

目前我们实现的二级缓存是每个服务的,此时缓存是在单个服务器上,如果我们想要实现分布式缓存的话,此时我们就需要考虑 Redis 来做我们的缓存服务。
所以接下来,我们将对 MyBatis 和 Redis 进行一个整合。
在 MyBatis 中,提供了一个针对 Cache 的接口,MyBatis 还提供了一个针对 Cache 接口的 Redis 实现类,该类存在在 myBatis-redis 包中。

pom.xml

<dependency>    <groupId>org.mybatis.caches</groupId>    <artifactId>mybatis-redis</artifactId>    <version>1.0.0-beta2</version></dependency>

编写代码

UserCacheMapper.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="icu.wzk.mapper.UserCacheMapper">    <!--开启二级缓存-->    <cache type="org.mybatis.caches.redis.RedisCache"></cache>    <resultMap id="userMap" type="icu.wzk.model.WzkUser">        <result column="id" property="id"></result>        <result column="username" property="username"></result>        <result column="password" property="password"></result>        <result column="birthday" property="birthday"></result>        <collection property="orderList" ofType="icu.wzk.model.WzkOrder">            <result column="oid" property="id"></result>            <result column="ordertime" property="ordertime"></result>            <result column="total" property="total"></result>        </collection>    </resultMap>    <select id="findAll" resultMap="userMap" useCache="true">        select *,o.id oid from wzk_user u left join wzk_orders o on u.id=o.uid;    </select></mapper>

UserCacheMapper.java

public interface UserCacheMapper {    List<WzkUser> findAll();}

redis.properties

redis.host=10.10.52.11redis.port=31679redis.connectionTimeout=5000redis.password=redis.database=0

测试代码

public class WzkicuCache05 {    public static void main(String[] args) throws IOException {        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()                .build(inputStream);        SqlSession sqlSession1 = sqlSessionFactory.openSession();        SqlSession sqlSession2 = sqlSessionFactory.openSession();        UserCacheMapper userCacheMapper1 = sqlSession1.getMapper(UserCacheMapper.class);        UserCacheMapper userCacheMapper2 = sqlSession2.getMapper(UserCacheMapper.class);        List<WzkUser> wzkUserList = userCacheMapper1.findAll();        for (WzkUser wu : wzkUserList) {            System.out.println(wu);        }        sqlSession1.close();        List<WzkUser> wzkUserList2 = userCacheMapper2.findAll();        for (WzkUser wu : wzkUserList2) {            System.out.println(wu);        }        sqlSession2.close();    }}

运行结果

WzkUser(id=1, username=wzk-update, password=123-update, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=[WzkOrder(id=1, ord

对应的结果如下图所示:
在这里插入图片描述
这里代码我运行了多次,可以看到请求都不会发出了,因为在 Redis 上缓存了。

源码分析

RedisCache 和其他的缓存方案基本是相似的,无非是实现了 Cache 接口,并使用 Jedis 操作缓存。

public final class RedisCache implements Cache {    private final String id;    private final JedisPool pool;    public RedisCache(final String id) {        if (id == null) {            throw new IllegalArgumentException("Cache instances require an ID");        }        this.id = id;        RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration();        pool = new JedisPool(                redisConfig,                redisConfig.getHost(),                redisConfig.getPort(),                redisConfig.getConnectionTimeout(),                redisConfig.getSoTimeout(),                redisConfig.getPassword(),                redisConfig.getDatabase(),                redisConfig.getClientName()        );    }}

RedisCache 在启动的时候,由 MyBatis 的 CacheBuilder 创建,创建的方式很简单,就是调用 RedisCache 的带有 String 参数的构造方法,即 RedisCache(String id),而 RedisCache 的构造方法中,调用了 RedisConfigurationBuilder 来创建对象 RedisConfig 对象,并使用 RedisConfig 来创建 JedisPool。

RedisConfig 继承了 JedisPoolConfig,提供了多个参数,这里的属性如下:

private String host = Protocol.DEFAULT_HOST;private int port = Protocol.DEFAULT_PORT;private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;private int soTimeout = Protocol.DEFAULT_TIMEOUT;private String password;private int database = Protocol.DEFAULT_DATABASE;private String clientName;

对应的截图如下所示:
在这里插入图片描述
RedisConfig 对象是由 RedisConfigurationBuilder 创建的,简单看下这个类,最重要的方法就是 parse 的部分:

public RedisConfig parseConfiguration(ClassLoader classLoader) {        Properties config = new Properties();        InputStream input = classLoader.getResourceAsStream(this.redisPropertiesFilename);        if (input != null) {            try {                config.load(input);            } catch (IOException var12) {                throw new RuntimeException("An error occurred while reading classpath property '" + this.redisPropertiesFilename + "', see nested exceptions", var12);            } finally {                try {                    input.close();                } catch (IOException var11) {                }            }        }        RedisConfig jedisConfig = new RedisConfig();        this.setConfigProperties(config, jedisConfig);        return jedisConfig;    }

对应的截图如下所示:
在这里插入图片描述
我们从这里看出,从 classpath 下读取了一个 redis.properties:

private final String redisPropertiesFilename = System.getProperty("redis.properties.filename", "redis.properties");

并将该配置文件中内容设置到了 RedisConfig 对象中,并返回,接下来,就是 RedisCache 使用 RedisConfig 类创建完成 JedisPool。

在 RedisCache 中,有一个模板方法:

  private Object execute(RedisCallback callback) {    Jedis jedis = pool.getResource();    try {      return callback.doWithRedis(jedis);    } finally {      jedis.close();    }  }

对应的截图如下所示:
在这里插入图片描述

模板接口为 RedisCallback,接口中只实现了一个 doWithRedis 方法而已:

package org.mybatis.caches.redis;import redis.clients.jedis.Jedis;public interface RedisCallback {Object doWithRedis(Jedis jedis);}

对应的截图如下所示:
在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/209186.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1