SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置
项目环境: 在SpringMVC + MyBatis + Mysql。Redis部署在Linux虚拟机。
1、整体思路
- 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅)
 - 使用Spring管理Redis连接池
 - 模仿EhcacheCache,实现RedisCache
 
2、pom.xml中加入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>
<!-- Ehcache实现,用于参考 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.0</version>
</dependency>
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 
3、引入applicationContext.xml中引入redis配置
<!-- 引入数据库配置文件 -->
<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>
<!-- 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.strive.cms.cache.RedisCacheTransfer">
    <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
</bean>
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 
4、创建缓存实现类RedisCache
/**
 *
 * @描述: 使用第三方内存数据库Redis作为二级缓存
 * @版权: Copyright (c) 2016
 * @作者: xiad
 * @版本: 1.0
 * @创建日期: 2016年3月2日
 * @创建时间: 下午8:02:57
 */
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()
    {
        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;
    }
}
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 - 24
 - 25
 - 26
 - 27
 - 28
 - 29
 - 30
 - 31
 - 32
 - 33
 - 34
 - 35
 - 36
 - 37
 - 38
 - 39
 - 40
 - 41
 - 42
 - 43
 - 44
 - 45
 - 46
 - 47
 - 48
 - 49
 - 50
 - 51
 - 52
 - 53
 - 54
 - 55
 - 56
 - 57
 - 58
 - 59
 - 60
 - 61
 - 62
 - 63
 - 64
 - 65
 - 66
 - 67
 - 68
 - 69
 - 70
 - 71
 - 72
 - 73
 - 74
 - 75
 - 76
 - 77
 - 78
 - 79
 - 80
 - 81
 - 82
 - 83
 - 84
 - 85
 - 86
 - 87
 - 88
 - 89
 - 90
 - 91
 - 92
 - 93
 - 94
 - 95
 - 96
 - 97
 - 98
 - 99
 - 100
 - 101
 - 102
 - 103
 - 104
 - 105
 - 106
 - 107
 - 108
 - 109
 - 110
 - 111
 - 112
 - 113
 - 114
 - 115
 - 116
 - 117
 - 118
 - 119
 - 120
 - 121
 - 122
 - 123
 - 124
 - 125
 - 126
 - 127
 - 128
 - 129
 - 130
 - 131
 - 132
 - 133
 - 134
 - 135
 - 136
 - 137
 - 138
 - 139
 - 140
 - 141
 - 142
 - 143
 - 144
 - 145
 - 146
 - 147
 - 148
 - 149
 - 150
 - 151
 - 152
 - 153
 - 154
 - 155
 - 156
 - 157
 - 158
 - 159
 - 160
 - 161
 - 162
 
5、创建中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入
/**
 *
 * @描述: 静态注入中间类
 * @版权: Copyright (c) 2016
 * @作者: xiad
 * @版本: 1.0
 * @创建日期: 2016年3月2日
 * @创建时间: 下午8:02:57
 */
public class RedisCacheTransfer
{
    @Autowired
    public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
        RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
    }
}
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 
6、配置文件redis.properties
# Redis settings
redis.host=192.168.25.132
redis.port=6379
redis.pass=
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true  
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 
7、mapper中加入MyBatis二级缓存
<mapper namespace="com.strive.cms.dao.site.CatalogMapper" >
  <cache type="com.strive.cms.cache.RedisCache"/>
  .....
</mapper>
- 1
 - 2
 - 3
 - 4
 
8、Mybatis全局配置
<?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的缓存,延迟加载等等一系列属性 -->
    <settings>
        <!-- 全局映射器启用缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 查询时,关闭关联对象即时加载以提高性能 -->
        <setting name="lazyLoadingEnabled" value="false"/>
        <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
        <setting name="multipleResultSetsEnabled" value="true"/>
        <!-- 允许使用列标签代替列名 -->
        <setting name="useColumnLabel" value="true"/>
        <!-- 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
        <setting name="useGeneratedKeys" value="false"/>
        <!-- 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>
        <!-- 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE -->
        <!-- <setting name="defaultExecutorType" value="BATCH" /> -->
        <!-- 数据库超过25000秒仍未响应则超时 -->
        <!-- <setting name="defaultStatementTimeout" value="25000" /> -->
        <!-- Allows using RowBounds on nested statements -->
        <setting name="safeRowBoundsEnabled" value="false"/>
        <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT
            local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. -->
        <setting name="localCacheScope" value="SESSION"/>
        <!-- Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers require specifying the column JDBC type but others work with generic values
            like NULL, VARCHAR or OTHER. -->
        <setting name="jdbcTypeForNull" value="OTHER"/>
        <!-- Specifies which Object's methods trigger a lazy load -->
        <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
        <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>
</configuration>
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 - 24
 - 25
 - 26
 - 27
 - 28
 - 29
 - 30
 - 31
 - 32
 - 33
 - 34
 - 35
 - 36
 - 37
 - 38
 - 39
 - 40
 - 41
 - 42
 - 43
 - 44
 - 45
 - 46
 - 47
 - 48
 - 49
 - 50
 - 51
 - 52
 - 53
 - 54
 - 55
 
9、打印Sql日志,方便测试
#定义LOG输出级别为INFO
log4j.rootLogger=INFO,Console,File
####定义日志输出目的地为控制台
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
#可以灵活地指定日志输出格式,下面一行是指定具体的格式
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
####文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.File = org.apache.log4j.RollingFileAppender
#指定输出目录
log4j.appender.File.File = logs/ssm.log
#定义文件最大大小
log4j.appender.File.MaxFileSize = 10MB
#输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志
log4j.appender.File.Threshold = ALL
log4j.appender.File.layout = org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n
####显示本项目SQL语句部分
log4j.logger.com.strive.cms=DEBUG
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 
10、测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MyBatisCacheSecondTest
{
    private static final Logger logger = LoggerFactory.getLogger(MyBatisCacheSecondTest.class);    
    @Autowired
    private  SiteService service;
    /*
     * 二级缓存测试
     */
    @Test
    public void testCache2() {
        PageInfo<Site> page1 = service.querySite("", 1, 2, "", "");
        logger.info(page1.getList().get(1).getName());
        PageInfo<Site> page2 = service.querySite("", 2, 2, "", "");
        logger.info(page2.getList().get(0).getName());
        PageInfo<Site> page3 = service.querySite("", 1, 2, "", "");
        logger.info(page3.getList().get(0).getName());
    }   
}
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 - 24
 - 25
 
首次运行结果 
后续运行结果 
同条件的查询语句可以发现,已经不再查询Mysql,而是直接取Redis数据 
查看Redis数据库 keys *, 会发现多了很多数据,结果如下 
至此,Redis基本配置成功。
如有疑问或建议,欢迎留言与指点
SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置的更多相关文章
- SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置
		
转载:http://blog.csdn.net/xiadi934/article/details/50786293 项目环境: 在SpringMVC +Spring + MyBatis + MySQL ...
 - mybatis 使用redis实现二级缓存(spring boot)
		
mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...
 - Mybatis整合Redis实现二级缓存
		
Mybatis集成ehcache . 为什么需要缓存 拉高程序的性能 . 什么样的数据需要缓存 很少被修改或根本不改的数据 业务场景比如:耗时较高的统计分析sql.电话账单查询sql等 . ehcac ...
 - springboot+mybatis 用redis作二级缓存
		
1.加入相关依赖包: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
 - mybatis结合redis实战二级缓存(六)
		
之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...
 - SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭
		
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...
 - mybatis结合redis实战二级缓存
		
之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...
 - SSM+redis整合(mybatis整合redis做二级缓存)
		
SSM:是Spring+Struts+Mybatis ,另外还使用了PageHelper 前言: 这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷 ...
 - mybatis 整合redis作为二级缓存
		
核心关键在于定义一个RedisCache实现mytis实现的Cache接口 ** * @author tele * @Description RedisCache由于需要传入id, 由mybatis进 ...
 
随机推荐
- shellb编程  之  实践出真知
			
1.查询file1 里面空行的所在行号 纯空行:awk ‘{if($0~/^$/)print NR}’ file 空行和带空格,制表符等的行:awk '$0~/^\s*$/' file 2.查询fil ...
 - X86架构
			
在接触BIOS的时候,都需要对PC架构有一定的认知.目前的PC架构绝大多数都是Intel的X86架构,貌似也是因为INTEL的这个X86架构早就了目前INTEL如日中天的地位. 废话不多说,X86架构 ...
 - go学习笔记
			
安装 brew install go 国际惯例hello,world. 创建文件hello.go go文件的main方法为函数的主入口,必须有这个方法. hello.go package main i ...
 - 华为QUIDWAY系列路由器的负载均衡配置
			
作者:邓聪聪 华为系列路由器的负载均衡NQA联动侦测配置案例: 需求:该局域网,IP地址(末位奇数)走联通,IP地址(末位偶数)走电信当某个运营商不可达时,自动切换.通过NQA来确定运营商是否可达., ...
 - python3+requests库框架设计05-unittest单元测试框架
			
unittest单元测试框架,主要由四部分组成:测试固件.测试用例.测试套件.测试执行器 测试固件(test fixture) 测试固件有两部分,执行测试前的准备部分setUp(),测试执行完后的清扫 ...
 - 解决python发送multipart/form-data请求上传文件的问题
			
服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件. 常用的方式一般如下: data = { 'name': 'nginx' } file ...
 - thinkphp验证码不显示
			
1.安装php的GD库 yum -y install php-gd 2.在输出图片前header("content-type: image/png"); 写入 header(&qu ...
 - UPS不间断电源工作原理简述
			
原文地址:https://blog.csdn.net/uamix/article/details/52776297 一.定义 UPS即不间断电源,是将蓄电池(多为铅酸免维护蓄电池)与主机相连接,通过主 ...
 - sqlserver 导出数据
			
背景 一看到这个标题,还有这个内容,感觉当初记录这个知识点真是记录的太简单了.不过通过这个知识点我还真想起了当初的一些事情.写的题外话可能更有意思,希望每篇文章我都能加个当时的题外记录.当时一直搞or ...
 - 【原创】运维基础之Docker(6)性能
			
The general result is that Docker is nearly identical to Native performance and faster than KVM in e ...