ssm整合redis和mysql_redis与ssm整合方法(mybatis二级缓存)

SSM+redis整合

ssm框架之前已经搭建过了,这里不再做代码复制工作。

这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷新已有缓存,如果不存在就会新建缓存,所有的insert,update操作都会更新缓存。

redis的好处也显而易见,可以使系统的数据访问性能更高。本节只是展示了整合方法和效果,后面会补齐redis集群、负载均衡和session共享的文章。

下面就开始整合工作:

c984f167c8e021c1ec0d4cc933254e04.png

后台首先启动redis-server(后台启动与远程连接linux服务的方法都需要改redis.conf文件),启动命令“./src/redis-server ./redis.conf”

我这里是windows系统下开发的,推荐一个可视化工具“Redis Desktop manager”,需要远程连接linux下的redis,需要linux下开启端口对外开放(具体方法是修改/etc/sysconfig/iptables文件,增加对外端口开发命令)。

以上操作都完成后,即可远程连接成功了,如图:

070ad47ccb862f53bd14afcd014941d7.png

bc7d419dce98ddc0144e37b116d878dc.png

现在还没有缓存记录,下面进入代码阶段,首先在pom.xml中增加需要的redis jar包

redis.clients

jedis

2.9.0

org.springframework.data

spring-data-redis

1.6.2.RELEASE

org.mybatis

mybatis-ehcache

1.0.0

com.alibaba

druid

1.0.24

pom.xml写好后,还需要新增两个配置文件:redis.properties

redis.host=192.168.0.109

redis.port=6379

redis.pass=123456

redis.maxIdle=200

redis.maxActive=1024

redis.maxWait=10000

redis.testOnBorrow=true

其中字段也都很好理解,再加入配置文件:spring-redis.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:task="http://www.springframework.org/schema/task"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

http://www.springframework.org/schema/util

http://www.springframework.org/schema/util/spring-util-4.3.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.3.xsd">

配置文件写好后,就开始java代码的编写:

JedisClusterFactory.java

package com.cjl.util;

import java.util.HashSet;

import java.util.Properties;

import java.util.Set;

import java.util.regex.Pattern;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import org.springframework.beans.factory.FactoryBean;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.core.io.Resource;

import redis.clients.jedis.HostAndPort;

import redis.clients.jedis.JedisCluster;

public class JedisClusterFactory implements FactoryBean, InitializingBean {

private Resource addressConfig;

private String addressKeyPrefix;

private JedisCluster jedisCluster;

private Integer timeout;

private Integer maxRedirections;

private GenericObjectPoolConfig genericObjectPoolConfig;

private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

public JedisCluster getObject() throws Exception {

return jedisCluster;

}

public Class extends JedisCluster> getObjectType() {

return (this.jedisCluster != null ? this.jedisCluster.getClass() : JedisCluster.class);

}

public boolean isSingleton() {

return true;

}

private Set parseHostAndPort() throws Exception {

try {

Properties prop = new Properties();

prop.load(this.addressConfig.getInputStream());

Set haps = new HashSet();

for (Object key : prop.keySet()) {

if (!((String) key).startsWith(addressKeyPrefix)) {

continue;

}

String val = (String) prop.get(key);

boolean isIpPort = p.matcher(val).matches();

if (!isIpPort) {

throw new IllegalArgumentException("ip 或 port 不合法");

}

String[] ipAndPort = val.split(":");

HostAndPort hap = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]));

haps.add(hap);

}

return haps;

} catch (IllegalArgumentException ex) {

throw ex;

} catch (Exception ex) {

throw new Exception("解析 jedis 配置文件失败", ex);

}

}

public void afterPropertiesSet() throws Exception {

Set haps = this.parseHostAndPort();

jedisCluster = new JedisCluster(haps, timeout, maxRedirections, genericObjectPoolConfig);

}

public void setAddressConfig(Resource addressConfig) {

this.addressConfig = addressConfig;

}

public void setTimeout(int timeout) {

this.timeout = timeout;

}

public void setMaxRedirections(int maxRedirections) {

this.maxRedirections = maxRedirections;

}

public void setAddressKeyPrefix(String addressKeyPrefix) {

this.addressKeyPrefix = addressKeyPrefix;

}

public void setGenericObjectPoolConfig(GenericObjectPoolConfig genericObjectPoolConfig) {

this.genericObjectPoolConfig = genericObjectPoolConfig;

}

}

RedisCache.java

package com.cjl.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.jedis.JedisConnection;

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;

public class RedisCache implements Cache {

private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);

private static JedisConnectionFactory jedisConnectionFactory;

private final String id;

private final ReadWriteLock rwl = 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;

}

/**

* 清空所有缓存

*/

public void clear() {

rwl.readLock().lock();

JedisConnection connection = null;

try {

connection = jedisConnectionFactory.getConnection();

connection.flushDb();

connection.flushAll();

} catch (JedisConnectionException e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.close();

}

rwl.readLock().unlock();

}

}

public String getId() {

return this.id;

}

/**

* 获取缓存总数量

*/

public int getSize() {

int result = 0;

JedisConnection connection = null;

try {

connection = jedisConnectionFactory.getConnection();

result = Integer.valueOf(connection.dbSize().toString());

logger.info("添加mybaits二级缓存数量:" + result);

} catch (JedisConnectionException e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.close();

}

}

return result;

}

public void putObject(Object key, Object value) {

rwl.writeLock().lock();

JedisConnection connection = null;

try {

connection = jedisConnectionFactory.getConnection();

RedisSerializer serializer = new JdkSerializationRedisSerializer();

connection.set(SerializeUtil.serialize(key), SerializeUtil.serialize(value));

logger.info("添加mybaits二级缓存key=" + key + ",value=" + value);

} catch (JedisConnectionException e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.close();

}

rwl.writeLock().unlock();

}

}

public Object getObject(Object key) {

// 先从缓存中去取数据,先加上读锁

rwl.readLock().lock();

Object result = null;

JedisConnection connection = null;

try {

connection = jedisConnectionFactory.getConnection();

RedisSerializer serializer = new JdkSerializationRedisSerializer();

result = serializer.deserialize(connection.get(serializer.serialize(key)));

logger.info("命中mybaits二级缓存,value=" + result);

} catch (JedisConnectionException e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.close();

}

rwl.readLock().unlock();

}

return result;

}

public Object removeObject(Object key) {

rwl.writeLock().lock();

JedisConnection connection = null;

Object result = null;

try {

connection = jedisConnectionFactory.getConnection();

RedisSerializer serializer = new JdkSerializationRedisSerializer();

result = connection.expire(serializer.serialize(key), 0);

} catch (JedisConnectionException e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.close();

}

rwl.writeLock().unlock();

}

return result;

}

public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {

RedisCache.jedisConnectionFactory = jedisConnectionFactory;

}

public ReadWriteLock getReadWriteLock() {

// TODO Auto-generated method stub

return rwl;

}

}

RedisCacheTransfer.java

package com.cjl.util;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

/**

* 静态注入中间类

*/

public class RedisCacheTransfer {

@Autowired

public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {

RedisCache.setJedisConnectionFactory(jedisConnectionFactory);

}

}

SerializeUtil.java

package com.cjl.util;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

/**

*

* @author cjl

*

*/

public class SerializeUtil {

/**

* 序列化

*/

public static byte[] serialize(Object object) {

ObjectOutputStream oos = null;

ByteArrayOutputStream baos = null;

try {

// 序列化

baos = new ByteArrayOutputStream();

oos = new ObjectOutputStream(baos);

oos.writeObject(object);

byte[] bytes = baos.toByteArray();

return bytes;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

/**

*反序列化

*/

public static Object unserialize(byte[] bytes) {

if (bytes !=null) {

ByteArrayInputStream bais = null;

try {

// 反序列化

bais = new ByteArrayInputStream(bytes);

ObjectInputStream ois = new ObjectInputStream(bais);

return ois.readObject();

} catch (Exception e) {

}

}

return null;

}

}

所有东西准备齐全后还需要修改映射文件

2b242cb434136dc1d7a4c5f84a7cd631.png

要使mybaits缓存生效,还需如上图这样开启二级缓存。配置文件还需要在web.xml中加载生效

23a64811962f56fa87811be001b86d40.png

一切准备就绪后,启动服务

632270aabc6232ef29b56884bb730aca.png

启动成功后,点击员工表单可以触发查询所有员工的方法,第一次进行查询语句可以看到mybatis打印了查询语句,并在redis服务器中更新了一条缓存

e98fbc0afcd61a321548ef0ed4254085.png

36067ca11917183c40c0481bf1350ab9.png

我们清空控制台再次点击查询员工按钮执行查询方法,可以看到没有执行查询语句,证明第二次查询直接从缓存中取值,没有连接mysql进行查询。

35448b5066a8d5dce8d8ba44520eb961.png

总结

以上所述是小编给大家介绍的redis与ssm整合方法(mybatis二级缓存),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值