• SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置


    转载:http://blog.csdn.net/xiadi934/article/details/50786293

    项目环境: 在SpringMVC +Spring + MyBatis + MySQLRedis部署在Linux虚拟机。

    1、整体思路

    • 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅)
    • 使用Spring管理Redis连接池
    • 模仿EhcacheCache,实现RedisCache

    2、pom.xml中加入Maven依赖

    复制代码
     1 <!-- spring-redis实现 -->
     2 <dependency>
     3     <groupId>org.springframework.data</groupId>
     4     <artifactId>spring-data-redis</artifactId>
     5     <version>1.6.2.RELEASE</version>
     6 </dependency>
     7 <!-- redis客户端jar -->
     8 <dependency>
     9     <groupId>redis.clients</groupId>
    10     <artifactId>jedis</artifactId>
    11     <version>2.8.0</version>
    12 </dependency>
    13 <!-- Ehcache实现,用于参考 -->
    14 <dependency>
    15     <groupId>org.mybatis</groupId>
    16     <artifactId>mybatis-ehcache</artifactId>
    17     <version>1.0.0</version>
    18 </dependency>
    复制代码

    3、引入applicationContext.xml中引入redis配置

    复制代码
     1 <!-- 引入数据库配置文件 -->
     2 <bean id="propertyConfigurer"    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     3     <property name="locations">
     4         <list>
     5             <value>classpath:jdbc.properties</value>
     6             <value>classpath:redis.properties</value>
     7         </list>
     8     </property>
     9 </bean>
    10 <!-- redis数据源 -->
    11 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
    12     <property name="maxIdle" value="${redis.maxIdle}" />  
    13     <property name="maxTotal" value="${redis.maxActive}" />  
    14     <property name="maxWaitMillis" value="${redis.maxWait}" />  
    15     <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
    16 </bean>
    17 <!-- Spring-redis连接池管理工厂 -->
    18 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  
    19     p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"  p:pool-config-ref="poolConfig"/>  
    20 <!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
    21 <bean id="redisCacheTransfer" class="com.strive.cms.cache.RedisCacheTransfer">
    22     <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
    23 </bean>
    复制代码

    4、创建缓存实现类RedisCache

    复制代码
      1 /**
      2  * 
      3  * @描述: 使用第三方内存数据库Redis作为二级缓存
      4  * @版权: Copyright (c) 2016 
      5  * @作者: xiad
      6  * @版本: 1.0 
      7  * @创建日期: 2016年3月2日 
      8  * @创建时间: 下午8:02:57
      9  */
     10 public class RedisCache implements Cache
     11 {
     12     private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
     13 
     14     private static JedisConnectionFactory jedisConnectionFactory;
     15 
     16     private final String id;
     17 
     18     /**
     19      * The {@code ReadWriteLock}.
     20      */
     21     private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
     22 
     23     public RedisCache(final String id) {
     24         if (id == null) {
     25             throw new IllegalArgumentException("Cache instances require an ID");
     26         }
     27         logger.debug("MybatisRedisCache:id=" + id);
     28         this.id = id;
     29     }
     30 
     31     @Override
     32     public void clear()
     33     {
     34         JedisConnection connection = null;
     35         try
     36         {
     37             connection = jedisConnectionFactory.getConnection();
     38             connection.flushDb();
     39             connection.flushAll();
     40         }
     41         catch (JedisConnectionException e)
     42         {
     43             e.printStackTrace();
     44         }
     45         finally
     46         {
     47             if (connection != null) {
     48                 connection.close();
     49             }
     50         }
     51     }
     52 
     53     @Override
     54     public String getId()
     55     {
     56         return this.id;
     57     }
     58 
     59     @Override
     60     public Object getObject(Object key)
     61     {
     62         Object result = null;
     63         JedisConnection connection = null;
     64         try
     65         {
     66             connection = jedisConnectionFactory.getConnection();
     67             RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
     68             result = serializer.deserialize(connection.get(serializer.serialize(key)));
     69         }
     70         catch (JedisConnectionException e)
     71         {
     72             e.printStackTrace();
     73         }
     74         finally
     75         {
     76             if (connection != null) {
     77                 connection.close();
     78             }
     79         }
     80         return result;
     81     }
     82 
     83     @Override
     84     public ReadWriteLock getReadWriteLock()
     85     {
     86         return this.readWriteLock;
     87     }
     88 
     89     @Override
     90     public int getSize()
     91     {
     92         int result = 0;
     93         JedisConnection connection = null;
     94         try
     95         {
     96             connection = jedisConnectionFactory.getConnection();
     97             result = Integer.valueOf(connection.dbSize().toString());
     98         }
     99         catch (JedisConnectionException e)
    100         {
    101             e.printStackTrace();
    102         }
    103         finally
    104         {
    105             if (connection != null) {
    106                 connection.close();
    107             }
    108         }
    109         return result;
    110     }
    111 
    112     @Override
    113     public void putObject(Object key, Object value)
    114     {
    115         JedisConnection connection = null;
    116         try
    117         {
    118             connection = jedisConnectionFactory.getConnection();
    119             RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
    120             connection.set(serializer.serialize(key), serializer.serialize(value));
    121         }
    122         catch (JedisConnectionException e)
    123         {
    124             e.printStackTrace();
    125         }
    126         finally
    127         {
    128             if (connection != null) {
    129                 connection.close();
    130             }
    131         }
    132     }
    133 
    134     @Override
    135     public Object removeObject(Object key)
    136     {
    137         JedisConnection connection = null;
    138         Object result = null;
    139         try
    140         {
    141             connection = jedisConnectionFactory.getConnection();
    142             RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
    143             result =connection.expire(serializer.serialize(key), 0);
    144         }
    145         catch (JedisConnectionException e)
    146         {
    147             e.printStackTrace();
    148         }
    149         finally
    150         {
    151             if (connection != null) {
    152                 connection.close();
    153             }
    154         }
    155         return result;
    156     }
    157 
    158     public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
    159         RedisCache.jedisConnectionFactory = jedisConnectionFactory;
    160     }
    161 
    162 }
    复制代码

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

    复制代码
     1 /**
     2  * 
     3  * @描述: 静态注入中间类
     4  * @版权: Copyright (c) 2016 
     5  * @作者: xiad
     6  * @版本: 1.0 
     7  * @创建日期: 2016年3月2日 
     8  * @创建时间: 下午8:02:57
     9  */
    10 public class RedisCacheTransfer 
    11 {
    12 
    13     @Autowired
    14     public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
    15         RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
    16     }
    17 
    18 }
    复制代码

    6、配置文件redis.properties

    复制代码
    1 # Redis settings  
    2 redis.host=192.168.25.132
    3 redis.port=6379  
    4 redis.pass=
    5 
    6 redis.maxIdle=300  
    7 redis.maxActive=600  
    8 redis.maxWait=1000  
    9 redis.testOnBorrow=true 
    复制代码

    7、mapper中加入MyBatis二级缓存

    <mapper namespace="com.strive.cms.dao.site.CatalogMapper" >
      <cache type="com.strive.cms.cache.RedisCache"/>
      .....
    </mapper>

    8、Mybatis全局配置

    复制代码
     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE configuration
     3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
     4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
     5 <configuration>
     6     <!-- 配置mybatis的缓存,延迟加载等等一系列属性 -->
     7     <settings>
     8 
     9         <!-- 全局映射器启用缓存 -->
    10         <setting name="cacheEnabled" value="true"/>
    11 
    12         <!-- 查询时,关闭关联对象即时加载以提高性能 -->
    13         <setting name="lazyLoadingEnabled" value="false"/>
    14 
    15         <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
    16         <setting name="multipleResultSetsEnabled" value="true"/>
    17 
    18         <!-- 允许使用列标签代替列名 -->
    19         <setting name="useColumnLabel" value="true"/>
    20 
    21         <!-- 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
    22         <setting name="useGeneratedKeys" value="false"/>
    23 
    24         <!-- 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL -->
    25         <setting name="autoMappingBehavior" value="PARTIAL"/>
    26 
    27         <!-- 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE -->
    28         <!-- <setting name="defaultExecutorType" value="BATCH" /> -->
    29 
    30         <!-- 数据库超过25000秒仍未响应则超时 -->
    31         <!-- <setting name="defaultStatementTimeout" value="25000" /> -->
    32 
    33         <!-- Allows using RowBounds on nested statements -->
    34         <setting name="safeRowBoundsEnabled" value="false"/>
    35 
    36         <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. -->
    37         <setting name="mapUnderscoreToCamelCase" value="true"/>
    38 
    39         <!-- 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 
    40             local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. -->
    41         <setting name="localCacheScope" value="SESSION"/>
    42 
    43         <!-- 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 
    44             like NULL, VARCHAR or OTHER. -->
    45         <setting name="jdbcTypeForNull" value="OTHER"/>
    46 
    47         <!-- Specifies which Object's methods trigger a lazy load -->
    48         <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    49 
    50         <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
    51         <setting name="aggressiveLazyLoading" value="true"/>
    52 
    53     </settings>
    54 
    55 </configuration>
    复制代码

    9、打印Sql日志,方便测试

    复制代码
     1 #定义LOG输出级别为INFO
     2 log4j.rootLogger=INFO,Console,File
     3 
     4 ####定义日志输出目的地为控制台
     5 log4j.appender.Console=org.apache.log4j.ConsoleAppender
     6 log4j.appender.Console.Target=System.out
     7 #可以灵活地指定日志输出格式,下面一行是指定具体的格式
     8 log4j.appender.Console.layout = org.apache.log4j.PatternLayout
     9 log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
    10 
    11 ####文件大小到达指定尺寸的时候产生一个新的文件
    12 log4j.appender.File = org.apache.log4j.RollingFileAppender
    13 #指定输出目录
    14 log4j.appender.File.File = logs/ssm.log
    15 #定义文件最大大小
    16 log4j.appender.File.MaxFileSize = 10MB
    17 #输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志
    18 log4j.appender.File.Threshold = ALL
    19 log4j.appender.File.layout = org.apache.log4j.PatternLayout
    20 log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c]%m%n
    21 
    22 ####显示本项目SQL语句部分
    23 log4j.logger.com.strive.cms=DEBUG
    复制代码

    10、测试代码

    复制代码
     1 @RunWith(SpringJUnit4ClassRunner.class)
     2 @ContextConfiguration(locations = {"classpath:applicationContext.xml"})  
     3 public class MyBatisCacheSecondTest
     4 {
     5     private static final Logger logger = LoggerFactory.getLogger(MyBatisCacheSecondTest.class);    
     6 
     7     @Autowired
     8     private  SiteService service;
     9 
    10     /*
    11      * 二级缓存测试
    12      */
    13     @Test
    14     public void testCache2() {
    15         PageInfo<Site> page1 = service.querySite("", 1, 2, "", "");
    16         logger.info(page1.getList().get(1).getName());
    17 
    18         PageInfo<Site> page2 = service.querySite("", 2, 2, "", "");
    19         logger.info(page2.getList().get(0).getName());
    20 
    21         PageInfo<Site> page3 = service.querySite("", 1, 2, "", "");
    22         logger.info(page3.getList().get(0).getName());
    23     }   
    24 
    25 }
    复制代码

    首次运行结果 
    这里写图片描述 
    后续运行结果 
    这里写图片描述 
    同条件的查询语句可以发现,已经不再查询Mysql,而是直接取Redis数据 
    查看Redis数据库 keys *, 会发现多了很多数据,结果如下 
    这里写图片描述 
    至此,Redis基本配置成功。

  • 相关阅读:
    SVM神经网络的术语理解
    优化问题中的正则项作用
    转 强烈推荐遗传算法入门例子
    21分钟 MySQL 入门教程
    C++中abs、fabs、fabsf的使用方法
    国内有哪些质量高的JAVA社区?
    <Eclipse 学习笔记> Eclipse 开发常用快捷键
    <Servlet 学习笔记 > Servlet 生命周期和工作原理
    HDU
    POJ
  • 原文地址:https://www.cnblogs.com/weixupeng/p/8540716.html
Copyright © 2020-2023  润新知