zoukankan      html  css  js  c++  java
  • mybatis-自定义缓存-redis二级缓存

    mybatis一级缓存二级缓存中已经介绍过了二级缓存的大致原理。下面我们用redis来实现一下二级缓存。环境是springmvc+mybatis+redis

    步骤一、引入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>

     步骤二、新建redis的配置redis.xml,redis.properties

    <?xml version="1.0" encoding="utf-8"?>
    <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"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.0.xsd"
           default-autowire="byName" default-lazy-init="false">
        <!--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:hostName="${redis.host}" p:port="${redis.port}"
                p:password="${redis.pass}" p:poolConfig-ref="poolConfig"/>
        <!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
        <bean id="redisCacheTransfer" class="com.yihaomen.mybatis.cache.RedisCacheTransfer">
            <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
        </bean>
    </beans>
    redis.host=192.168.31.55
    redis.port=6379
    redis.pass=
    redis.maxIdle=300
    redis.maxActive=600
    redis.maxWait=1000
    redis.testOnBorrow=true

    步骤三、将redis.xml引入到spring的配置文件applicationContext.xml

    <bean id="propertyConfigurer"
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath*:jdbc.properties</value>
                    <value>classpath*:redis.properties</value>
                </list>
            </property>
        </bean>
    <import resource="redis.xml"/>

     步骤四、创建缓存实现类RedisCache

    package com.yihaomen.mybatis.cache;
    
    import org.apache.ibatis.cache.Cache;
    import org.springframework.data.redis.connection.jedis.JedisConnection;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import redis.clients.jedis.exceptions.JedisConnectionException;
    
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     *   
     *  @ProjectName: springmvc-mybatis 
     *  @Description: 使用第三方内存数据库Redis作为二级缓存
     *  @author: lisen
     *  @date: 2017/11/8  
     */
    public class RedisCache implements Cache{
    
        private static JedisConnectionFactory jedisConnectionFactory;
    
        private final String id;
    
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    
        public RedisCache(final String id) {
            if(id == null) {
                throw new IllegalArgumentException("Cache instances require an ID");
            }
            this.id = id;
        }
    
        public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
            RedisCache.jedisConnectionFactory = jedisConnectionFactory;
        }
    
        @Override
        public String getId() {
            return this.id;
        }
    
        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();
                }
            }
        }
    
        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;
        }
    
        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;
        }
    
        @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();
                }
            }
        }
    
        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;
        }
    
        public ReadWriteLock getReadWriteLock() {
            return this.readWriteLock;
        }
    }

    步骤五、 创建中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入

    package com.yihaomen.mybatis.cache;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    
    /**
     *   
     *  @ProjectName: springmvc-mybatis 
     *  @Description: 创建中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入,
     *                静态注入中间类
     *  @author: lisen
     *  @date: 2017/11/8  
     */
    public class RedisCacheTransfer {
    
        @Autowired
        public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
            RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
        }
    }

     步骤六、在mapper(User.xml)中加入MyBatis二级缓存

    <?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="com.yihaomen.mybatis.dao.UserMapper">
        <cache type="com.yihaomen.mybatis.cache.RedisCache"/>
      <select id="selectUserByID" parameterType="int" resultType="User" >
      select * from `user` where id = #{id}
      </select>
    </mapper>

     我们还可以配置在SQL层面上的缓存配置,来决定它们是否需要使用或者刷新缓存,我们往往根据两个属性:userCache和flushCache来完成,其中userCache表示是否需要使用缓存,儿flushCache表示插入后是否需要刷新缓存,比如

    <select ... flushCache="false" useCache="true"/>

    <insert ... flushCache="true"/>

    <update... flushCache="true"/>

    <delete... flushCache="true"/>

     步骤七、在mybatis-config.xml文件中开启二级缓存

    <settings>
            <!--这个配置使全局的映射器(二级缓存)启用或禁用缓存-->
            <setting name="cacheEnabled" value="true" />
    </setting>

     步骤八、单元测试

    package com.yihaomen.service.test;
    
    import com.yihaomen.mybatis.dao.UserMapper;
    import com.yihaomen.mybatis.model.User;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import java.util.List;
    
    /**
     *   
     *  @ProjectName: springmvc-mybatis 
     *  @Description:
     *  @author: lisen
     *  @date: 2017/11/9  
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration({"classpath:applicationContext.xml"})
    public class UserSpringTest {
        @Autowired
        private UserMapper userMapper;
    
        @Test
        public void selectUserById() {
            List<User> users = userMapper.selectUserById(11L);
        }
    
    }

    https://gitee.com/huayicompany/springmvc-mybatis

    参考:

    [1]博客,http://blog.csdn.net/xiadi934/article/details/50786293

  • 相关阅读:
    匿名函数
    内置函数
    基础函数--3
    基础函数(2)
    基础函数(1)
    文件的相关操作
    知识点补充,set集合,深浅copy
    is 和 ==的区别
    Django-form组件中过滤当前用户信息
    Django的常用模块引入整理
  • 原文地址:https://www.cnblogs.com/happyflyingpig/p/7818280.html
Copyright © 2011-2022 走看看