zoukankan      html  css  js  c++  java
  • 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> 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>
    
        <!-- 使用mybatis方式全局变量设置在核心配置文件sqlMapConfig.xml的settings中
             spring和mybatis整合的情况下,mybatis下的全局参数<settings>在spring的配置文件中设置,
                在spring的sqlSessionFactory对象中,将配置粘入bean的property中
    
            settings用于配置全局变量,有顺序要求,要放在environment前面,配置全局参数
            lazyLoadingEnabled 配置懒加载,全局允许或静止懒加载,所有的任务都懒加载
            具体实现懒加载:通过在resultMap中设置fetchType实现懒加载
    
            <setting name="cacheEnabled" value="true"/> cacheEnabled允许二级缓存
        -->
        <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">
    
    
        <!-- 配置组件扫描器,使用注解方式开发,不用配置dao和service -->
        <!-- 在springmvc.xml文件中也可以配置这个属性 -->
        <context:component-scan base-package="com.lll"/>
    
        <!-- 数据源 -->
    <!--    <bean id="dataSource"-->
    <!--          class="org.springframework.jdbc.datasource.DriverManagerDataSource">-->
    <!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
    <!--        <property name="url" value="jdbc:mysql://localhost:3306/test"/>-->
    <!--        <property name="username" value="root"/>-->
    <!--        <property name="password" value=""/>-->
    <!--    </bean>-->
    
        <!-- 配置session工厂 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--        <property name="dataSource" ref="dataSource"/>-->
            <property name="configLocation" value="classpath:resource/mybatis-config.xml"/>
        </bean>
    
        <!-- 事务管理器 -->
        <!--     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"/>
            </bean> -->
    
        <!-- 配置AOP通知 -->
        <!--     <tx:advice id="txAdvice" transaction-manager="transactionManager">
                 配置事务属性
                 <tx:attributes>
                     添加事务管理的方法
                     <tx:method name="save*" propagation="REQUIRED"/>
                     <tx:method name="delete*" propagation="REQUIRED"/>
                     <tx:method name="update*" propagation="REQUIRED"/>
                     <tx:method name="select*" read-only="true"/>
                 </tx:attributes>
             </tx:advice> -->
    
        <!-- 配置AOP,为添加事务管理的操作配置AOP -->
        <!--     <aop:config>
                引入的Spring定义的事务通知,需要使用aop:advisor
                下面难
                <aop:advisor advice-ref="txAdvice"
                    pointcut="execution(* com.edu.test.service.*.*(..))"
                />
            </aop:config> -->
    </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)

    作者:CodingPanda
    座中铭:润物细无声,功到自然成
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    用javascript实现简单的用户登录验证
    JS创建数组的三种方法
    JS中的数据类型
    原始值和引用值
    html为什么用雪碧图的优缺点
    html,将元素水平,垂直居中的四种方式
    使用display:none和visibility:hidden隐藏的区别
    jsonview注解、RequestBody 、拦截
    02.实现图形验证码
    spring注解使用
  • 原文地址:https://www.cnblogs.com/LiLiliang/p/14590376.html
Copyright © 2011-2022 走看看