MyBatis(SSM框架)接入redis作为二级缓存(含源码)


1.配置jar包:

 可在(https://mvnrepository.com/)中下载

2.添加redis ip 和port配置

#redis配置 start
# redis地址
redis.ip=127.0.0.1
# redis端口
redis.port=6379
#  最大连接数
jedis.pool.maxActive=3000
#  空闲时最大连接数
jedis.pool.maxIdle=1000
#  最大等待时间
jedis.pool.maxWait=1500
jedis.pool.testOnBorrow=true
jedis.pool.testOnReturn=true
# 开关
redis.switch = true
#  redis的KEY,以这个开头,区分系统
redis.key = SOA
#redis配置 end

3.配置对应工具类

  RedisCache.Java

package com.lll.utils;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheException;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;

import java.io.Serializable;
import java.util.Properties;
import java.util.concurrent.locks.ReadWriteLock;

public class RedisCache implements Cache {

    private final String redisIp = PropertiesUtils.getProperty("redis.ip");
    private final int redisPort = Integer.valueOf(PropertiesUtils.getProperty("redis.port")).intValue();

    private final String id;

    private Jedis cache = new Jedis(redisIp, redisPort);

    public RedisCache(String id) {
        this.id = id;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    //返回缓存所有键值对的数量
    public int getSize() {
        Long dbSize = cache.dbSize();
        return dbSize.intValue();
    }

    @Override
    //向缓存中存入数据
    public void putObject(Object key, Object value) {
        System.out.println("key:" + key);
        //将对象序列化成字节数组  引入commens-lang3工具包
        byte[] keyBs = SerializeUtils.serialize((Serializable) key);
        byte[] valueBs = SerializeUtils.serialize((Serializable) value);

        cache.set(keyBs, valueBs);
    }

    @Override
    //从缓存中获取数据
    public Object getObject(Object key) {
        byte[] keyBs = SerializeUtils.serialize((Serializable) key);
        byte[] valueBs = cache.get(keyBs);
        if (valueBs != null) { // 第一次到缓存找数据的时候 , 返回的是null
            return SerializeUtils.unserialize(valueBs);
        }
        return null;
    }

    @Override
    //清除缓存
    public Object removeObject(Object key) {
        // 先获取一下删除的对象
        byte[] keyBs = SerializeUtils.serialize((Serializable) key);
        byte[] valueBs = cache.get(keyBs);
        Object obj = SerializeUtils.unserialize(valueBs);
        cache.del(keyBs);// 执行删除操作
        return obj;
    }

    @Override
    //清空缓存
    public void clear() {
        cache.flushDB();
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return null;
    }

    @Override
    public boolean equals(Object o) {
        if (getId() == null) {
            throw new CacheException("Cache instances require an ID.");
        }
        if (this == o) {
            return true;
        }
        if (!(o instanceof Cache)) {
            return false;
        }

        Cache otherCache = (Cache) o;
        return getId().equals(otherCache.getId());
    }

    @Override
    public int hashCode() {
        if (getId() == null) {
            throw new CacheException("Cache instances require an ID.");
        }
        return getId().hashCode();
    }

}

SerializeUtils.java

package com.lll.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeUtils {

    //private static final Logger logger = Logger.getLogger(SerializeUtils.class);

    private static void close(ObjectOutputStream objectOutputStream, ByteArrayOutputStream byteArrayOutputStream) {
        try {
            if (byteArrayOutputStream != null) {
                byteArrayOutputStream.close();
            }
            if (objectOutputStream != null) {
                objectOutputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            //logger.error("关闭IO资源异常[" + e.getMessage() + "]", e);
        }
    }

    private static void close(ObjectInputStream objectInputStream, ByteArrayInputStream byteArrayInputStream) {
        try {
            if (objectInputStream != null) {
                objectInputStream.close();
            }
            if (byteArrayInputStream != null) {
                byteArrayInputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            //logger.error("关闭IO资源异常[" + e.getMessage() + "]", e);
        }
    }

    public static byte[] serialize(Object object) {
        ObjectOutputStream objectOutputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(object);
            byte[] bytes = byteArrayOutputStream.toByteArray();
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            //logger.error("序列化对象异常[" + e.getMessage() + "]", e);
        } finally {
            close(objectOutputStream, byteArrayOutputStream);
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static  T unserialize(byte[] bytes) {
        if (bytes == null)
            return null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return (T) objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(objectInputStream, byteArrayInputStream);
        }
        return null;
    }

}

4.在mybatis-config.xml和spring-mybatis.xml开启配置

<?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="lazyLoadingEnabled" value="true"/>
        
        <setting name="aggressiveLazyLoading" value="false"/>
        
        <setting name="cacheEnabled" value="true"/>
    settings>

configuration>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


    
    
    <context:component-scan base-package="com.lll"/>

    








    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="configLocation" value="classpath:resource/mybatis-config.xml"/>
    bean>

    
    

    
    

    
    
beans>

5.在dao.xml中开启缓存

  <cache type="com.lll.utils.RedisCache" />

6.在sql方法中设置是都使用缓存

7.实际效果:

8.注意:bean对象必须实现Serializable,否则缓存会报错

9.资源

源码地址:https://github.com/CodingPandaLLL/springlll.git

资源包:https://codeload.github.com/CodingPandaLLL/springlll/zip/refs/tags/1.0.1

软件:Redis(提取码:vkun)、Redis Desktop Manager(提取码:2syd)