您的位置:首页 > 数据库 > Redis

spring mvc 小记(八):MyBatis整合redis缓存

2016-10-17 22:45 309 查看
使用spring mvc已有2年之久,却还是停留在使用阶段,感觉这么下去不是办法,所以还是想往深处一探究竟。
redis缓存

概念:Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value非关系型数据库,并提供多种语言的API。咱们平常所说的缓存,就是由它实现的,在于MyBatis的整合中中,用redis查询出来的数据,减轻数据库的压力,从而提高系统的性能。

要使用redis,得先下载,然后解压放到相应的文件夹下,若是在本地,使用命令窗口启动:切换到redis的目录,执行redis-server.exe
 redis.windows.donf命令,会看到有一个启动成功的标志显示,保持该窗口不被关闭。

项目中,在maven中引入相关配置:

<span style="font-size:18px;"><!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.4.RELEASE</version>
</dependency></span>
新建一个参数配置文件redis.properties:
<span style="font-size:18px;">redis.ip=127.0.0.1
redis.port=6379
redis.pool.maxWait=1000</span>
参考相关资料,新建一个cache类,取名为MybatisRedisCache,实现org.apache.ibatis.cache.Cache接口,具体代码如下:
<span style="font-size:18px;">public class MybatisRedisCache implements Cache {

private static Logger logger = Logger.getLogger(MybatisRedisCache.class);
private Jedis redisClient = createReids();

private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

private String id;

public MybatisRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require
4000
an ID");
}
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>MybatisRedisCache:id=" + id);
this.id = id;
}

@Override
public String getId() {
return this.id;
}

@Override
public int getSize() {

return Integer.valueOf(redisClient.dbSize().toString());
}

@Override
public void putObject(Object key, Object value) {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject:" + key + "=" + value+"\n");
redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));
}

@Override
public Object getObject(Object key) {
Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString())));
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>getObject:" + key + "=" + value);
return value;
}

@Override
public Object removeObject(Object key) {
return redisClient.expire(SerializeUtil.serialize(key.toString()), 0);
}

@Override
public void clear() {
redisClient.flushDB();
}

@Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}

protected Jedis createReids() {
String host = "localhost";
String port = "6379";
String timeout = "3000";
Properties prop =  new  Properties();
InputStream in = MybatisRedisCache.class.getClassLoader().getResourceAsStream( "redis.properties" );
try  {
prop.load(in);
host = prop.getProperty( "redis.ip" ).trim();
port = prop.getProperty( "redis.port" ).trim();
timeout = prop.getProperty( "redis.pool.maxWait" ).trim();
}  catch  (IOException e) {
e.printStackTrace();
}

JedisPool pool = new JedisPool(new JedisPoolConfig(),host ,Integer.parseInt(port),Integer.parseInt(timeout));
return pool.getResource();
}
}</span>
实现接口中相应的方法,方法中是调用redis的java客户端去操作缓存,被操作的数据需要被序列化或反序列化,这个可以到网上查找:java序列化。

进入Cache接口,可以看到对于该接口的描述其中有:

* One instance of cache will be created for each namespace.
*
* The cache implementation must have a constructor that receives the cache id as an String parameter.
*
* MyBatis will pass the namespace as id to the constructor.

翻译为:

* 将为每一个命名空间创建一个Cache的实例

* Cache接口的实现类必须有一个具有String类型参数的构造方法,用于接收Cache对象的id,作为其唯一标识

* mybatis将以namespace作为id调用这个构造函数创建对象

所以实现一个构造方法是必须的。

写完缓存实现类后,需要相应的配置,在MyBatis的xml配置文件中写入:

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

在相应的mapper映射文件中写入:

<!-- 缓存 -->
<cache eviction="LRU" type="com.jk.redis.MybatisRedisCache" />

至此MyBatis+redis配置完成,在对数据库做相应的操作时,可以看到MybatisRedisCache类中相关的putObject、getObject日志输出,在第二次做同样的查询时,只看到getObject,说明是直接从缓存里去取值了。或者开sql日志的可以试试,在第二次相同查询时,sql语句不会输出,也可以说名改数据是从缓存中获取了。

还是附一个序列化的“小栗子”:

public static void main(String [] args){
User user = new User();
user.setUserName("guyueliusu");
user.setUserDesc("to be stronger");

try {
//序列化
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(user);
byte[] b = outputStream.toByteArray();

//反序列化
ByteArrayInputStream inputStream = new ByteArrayInputStream(b);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
User uu = (User) objectInputStream.readObject();

System.out.println("========"+uu.getUserName());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring mvc mybatis redis