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

来源:互联网 发布:女生英文名推荐 知乎 编辑:程序博客网 时间:2024/05/16 11:18

使用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.1redis.port=6379redis.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 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();        }    }





0 0
原创粉丝点击