操作步骤:
1.使用maven导入包
<!-- 导入redis包 -->
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.4.RELEASE</version>
</dependency>
<!-- redis客户端jar -->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- Ehcache实现,用于参考 -->
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
2.RedisCache类
package com.hlx.util;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
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;
/**
*
* 使用第三方内存数据库Redis作为二级缓存
*
* 这个类实现了mybatis中的缓存机制
*
*/
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}.
* ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
*
* http://blog.csdn.net/qq_19431333/article/details/70568478
*/
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
/**
* 获得缓存的ID
*
* @param id
*/
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() {
RedisConnection 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;
}
/**
* 通过key获得数据value
*/
@Override
public Object getObject(Object key) {
Object result = null;
RedisConnection 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;
RedisConnection 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;
}
/**
* 存入数据key-value
*/
@Override
public void putObject(Object key, Object value) {
RedisConnection 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();
}
}
}
/**
* 根据key删除数据
*/
@Override
public Object removeObject(Object key) {
RedisConnection 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;
}
/**
* 设置jedis连接工厂对象
*
* @param jedisConnectionFactory
*/
public static void setJedisConnectionFactory(
JedisConnectionFactory jedisConnectionFactory) {
RedisCache.jedisConnectionFactory = jedisConnectionFactory;
}
}
3.RedisCacheTransfer类
package com.hlx.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
/**
* 静态注入中间类
* @author Administrator
*
*/
public class RedisCacheTransfer {
@Autowired
public void setJedisConnectionFactory(
JedisConnectionFactory jedisConnectionFactory) {
RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
}
}
4.配置文件redis.properties
redis.host=192.168.0.101
redis.port=6379
redis.pass=
redis.maxIdle=600
redis.maxTotal=1024
redis.maxWait=10000
redis.testOnBorrow=true
5.配置文件applicationContext-redis.xml
<!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- 连接池配置,类似数据库连接池 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.pass}" />
<property name="poolConfig" ref="poolConfig" />
</bean>
<!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
<bean id="redisCacheTransfer" class="com.hlx.util.RedisCacheTransfer">
<property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
</bean>
6.配置文件mybatis-config.xml
<?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>
<!-- 全局setting配置,根据需要添加 -->
<!-- 配置mapper 由于使用spring和mybatis的整合包进行mapper扫描,这里不需要配置了。 必须遵循:mapper.xml和mapper.java文件同名且在一个目录 -->
<!-- 配置mybatis的缓存,延迟加载等等一系列属性 -->
<settings>
<!-- 指定日志输出 -->
<setting name="logImpl" value="LOG4J"/>
<!-- 全局映射器启用缓存 *主要将此属性设置完成即可 -->
<setting name="cacheEnabled" value="true" />
<!-- 查询时,关闭关联对象即时加载以提高性能 -->
<setting name="lazyLoadingEnabled" value="false" />
<!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
<setting name="aggressiveLazyLoading" value="true" />
</settings>
</configuration>
7.配置文件applicationContext-dao.xml
<!--3) myBatis文件 -->
<bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源 -->
<property name="dataSource" ref="druidDataSource" />
<!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 -->
<property name="mapperLocations" value="classpath:com/hlx/mapper/*Mapper.xml" />
<!-- 实体类的别名 -->
<property name="typeAliasesPackage" value="com.hlx.entity" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
8.在查询的实体类中配置BookMapper.xml
<?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.hlx.dao.BookMapper" >
<!-- 缓存类配置 -->
<cache eviction="LRU" type="com.hlx.util.RedisCache"/>
9.在Controller类中
@RequestMapping("/find2")
public String find(ModelMap model) {
// 调用业务方法
Book books = service.find(2);
System.out.println(books);
// 保存
model.put("book", books);
return "my";
}
10.实体类实现 implements Serializable
11.在JSP页面显示数据
<h1>${book.bid } ${book.bname } </h1>
13.如何查看是否用了缓存?
a)使用log4j.properties
log4j.rootLogger=DEBUG,CONSOLE,FILEOUT
log4j.addivity.org.apache=true
# CONSOLE \u6253\u5370\u5230\u63A7\u5236\u53F0
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss} \:%m%n
#
# FILEOUT \u6253\u5370\u5230 <span style="font-family: Arial, Helvetica, sans-serif;">D\:\\report.log</span>
log4j.appender.FILEOUT=org.apache.log4j.RollingFileAppender
log4j.appender.FILEOUT.File=D\:\\report.log
log4j.appender.FILEOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.fileout.MaxFileSize=100000KB
log4j.appender.FILEOUT.Append=true
#log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d \u2013 %c -%-4r [%t] %-5p %c %x \u2013 %m%n
log4j.appender.FILEOUT.layout.ConversionPattern=[%-5p]_%d{yyyy-MM-dd HH\:mm\:ss} \:%m%n
b)导入相关的包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
第一次查询
再次查询
再次查询
注意:后面查询相同就不会再产生SQL语句,就会到Redis缓存去查找!!