SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置
项目环境:在 SpringMVC + MyBatis + Mysql。Redis 部署在 Linux 虚拟机。
1、整体思路
参考 Ehcache 实现 MyBatis 二级缓存代码(Maven 引用对应 jar 查阅)
使用 Spring 管理 Redis 连接池
模仿 EhcacheCache,实现 RedisCache
2、pom.xml 中加入 Maven 依赖
[Java] 纯文本查看 复制代码
?
<!– 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>
3、引入 applicationContext.xml 中引入 redis 配置
[Java] 纯文本查看 复制代码
?
<!– 引入数据库配置文件 –>
<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>
4、创建缓存实现类 RedisCache
[Java] 纯文本查看 复制代码
?
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;}
}
5、创建中间类 RedisCacheTransfer,完成 RedisCache.jedisConnectionFactory 的静态注入
[Java] 纯文本查看 复制代码
?
public class RedisCacheTransfer
{
@Autowired
public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
}
}
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
7、mapper 中加入 MyBatis 二级缓存
[Java] 纯文本查看 复制代码
<mapper namespace=”com.strive.cms.dao.site.CatalogMapper” >
<cache type=”com.strive.cms.cache.RedisCache”/>
</mapper>
8、Mybatis 全局配置
[Java] 纯文本查看 复制代码
?
<?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>
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}%m%n
显示本项目 SQL 语句部分
log4j.logger.com.strive.cms=DEBUG