美文网首页SSM社区
mybatis整合redis缓存

mybatis整合redis缓存

作者: onlyHalfSoul | 来源:发表于2018-06-13 18:58 被阅读22次

    最近闲来无事开始学习缓存技术,首当其冲的就是接触到redis,多的不说,直接借着现有ssm框架整合redis进去,spring和mybatis对于redis的支撑做得很好,几乎只是几个对象注入和简单配置就完成了,简单了测试一下,感觉用着还不错,比mybatis自带的缓存好用,关于两者的对比后续会再发一篇说明。下面是我的整合步骤:

    下载redis软件

    我是直接在Windows上使用的,就下载了Windows版的,实际项目肯定都是Linux内核,换成Linux版的也就可以了。

    Window 下安装

    下载地址:https://github.com/MSOpenTech/redis/releases

    Linux 下安装

    下载地址:http://redis.io/download

    Windows版的运行相当简单,直接点击运行即可。


    Windows-redis启动.png

    引依赖

    整合redis需要的maven依赖如下:(网上有多种说法,本文引入亲测可用)

    <!-- spring-redis实现 -->
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-redis</artifactId>
                <version>1.6.2.RELEASE</version>
            </dependency>
            <!-- redis客户端jar -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.8.0</version>
            </dependency>
    

    当然必要的spring和mybatis的依赖也是必要的。

    spring整合redis

    spring整合redis也就是使用IOC容器生成redis所需的依赖注入,配置如下:

    <!-- redis数据源 -->
        <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxIdle" value="${redis.maxIdle}" />
            <property name="maxTotal" value="${redis.maxActive}" />
            <property name="maxWaitMillis" value="${redis.maxWait}" />
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean>
    
    <!-- Spring-redis连接池管理工厂 -->
        <bean id="jedisConnectionFactory"
              class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
              p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
              p:pool-config-ref="poolConfig" />
    
    <!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
        <bean id="redisCacheTransfer" class="com.trace.app.framework.annotation.RedisCacheTransfer">
            <property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
        </bean>
    
    
    <!-- 连接池基本参数配置,类似数据库连接池 -->
        <context:property-placeholder location="classpath*:redis.properties" />
        <bean name="genericObjectPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig" >
            <property name="maxWaitMillis" value="-1" />
            <property name="maxTotal" value="1000" />
            <property name="minIdle" value="8" />
            <property name="maxIdle" value="100" />
        </bean>
    

    redis的连接properties文件如下:

    # Redis settings
    redis.host=127.0.0.1
    redis.port=6379  
    redis.pass=
    
    redis.maxIdle=300  
    redis.maxActive=600  
    redis.maxWait=1000  
    redis.testOnBorrow=true
    

    spring读取properties文件配置如下:

    <bean id="propertyConfigurer" class="com.trace.app.framework.toolsmodel.ConvertPwdPropertyConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:jdbc.properties</value>
                    <value>classpath:redis.properties</value>
                </list>
            </property>
            <property name="fileEncoding" value="utf-8"></property>
    
        </bean>
    

    添加缓存接口实现类

    通过重写Cache类中的方法,将mybatis中默认的缓存空间映射到redis空间中。

    public class RedisCache implements Cache {
        private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
    
        private static JedisConnectionFactory jedisConnectionFactory;
    
        private final String id;
    
        /**
         * The {@code ReadWriteLock}.
         */
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    
        public RedisCache(final String id) {
            if (id == null) {
                throw new IllegalArgumentException("Cache instances require an ID");
            }
            logger.debug("MybatisRedisCache:id=" + id);
            this.id = id;
        }
    
        @Override
        public void clear() {
            JedisConnection connection = null;
            try {
                connection = jedisConnectionFactory.getConnection();
                connection.flushDb();
                connection.flushAll();
            } catch (JedisConnectionException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        }
    
        @Override
        public String getId() {
            return this.id;
        }
    
        @Override
        public Object getObject(Object key) {
            Object result = null;
            JedisConnection connection = null;
            try {
                connection = jedisConnectionFactory.getConnection();
                RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
                result = serializer.deserialize(connection.get(serializer.serialize(key)));
            } catch (JedisConnectionException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
            return result;
        }
    
        @Override
        public ReadWriteLock getReadWriteLock() {
            // TODO Auto-generated method stub
            return this.readWriteLock;
        }
    
        @Override
        public int getSize() {
            int result = 0;
            JedisConnection connection = null;
            try {
                connection = jedisConnectionFactory.getConnection();
                result = Integer.valueOf(connection.dbSize().toString());
            } catch (JedisConnectionException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
            return result;
        }
    
        @Override
        public void putObject(Object key, Object value) {
            JedisConnection connection = null;
            try {
                connection = jedisConnectionFactory.getConnection();
                RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
                connection.set(serializer.serialize(key), serializer.serialize(value));
            } catch (JedisConnectionException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        }
    
        @Override
        public Object removeObject(Object key) {
            JedisConnection connection = null;
            Object result = null;
            try {
                connection = jedisConnectionFactory.getConnection();
                RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
                result = connection.expire(serializer.serialize(key), 0);
            } catch (JedisConnectionException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
            return result;
        }
    
        public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
            RedisCache.jedisConnectionFactory = jedisConnectionFactory;
        }
    
    }
    
    

    静态注入类参考如下:

    /**
     *
     * @描述: 静态注入中间类
    
     */
    public class RedisCacheTransfer
    {
        @Autowired
        public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
            RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
        }
    }
    

    mybatis二级缓存调用第三方redis

    mybatis配置如下,

    <settings>
            <!-- 全局映射器启用缓存 -->
            <setting name="cacheEnabled" value="true"/>
            <!-- 允许JDBC支持生成的键 -->
            <setting name="useGeneratedKeys" value="true"/>
            <!-- 配置默认执行器 -->
            <setting name="defaultExecutorType" value="REUSE"/>
            <!-- 全局启用延迟加载 -->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!-- 设置超时时间 -->
            <setting name="defaultStatementTimeout" value="25000"/>
            <!--<setting name="autoMapperBehavior" value="Full"/>-->
            <!--打印sql日志-->
            <setting name="logImpl" value="STDOUT_LOGGING"/>
    
        </settings>
    

    打开cache二级缓存。

    在Mapper中添加二级缓存配置:

    <cache eviction="LRU" type="com.trace.app.framework.annotation.RedisCache" />
    

    对于增删改等更新数据库操作,需要加上 flushCache="true" ,示例如下:

    <update id="activateCompany" parameterType="int"  flushCache="true">
    update  sql ......
    </update>
    

    该字段会让更新语句执行后,刷新缓存,也就是清空缓存,避免查询信息显示不及时的问题。

    测试

    之后就可以直接用ssm的接口编程方式了,查询接口和更新接口执行后, redis控制台显示如下:

    redis控制台显示.png

    自此redis和ssm框架的整合就初步结束,小弟菜鸟一枚,欢迎批评指正。

    相关文章

      网友评论

        本文标题:mybatis整合redis缓存

        本文链接:https://www.haomeiwen.com/subject/kmhleftx.html