spring mvc @cache+redis 整合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38362455/article/details/81287489

一.spring cache和cache+redis的区别
1. 缓存级别不同
Spring cache是代码级的缓存,他一般是使用一个ConcurrentMap。也就是说实际上还是是使用JVM的内存来缓存对象的,那么肯定会造成大量的内存消耗。但是使用方便。
Redis 作为一个缓存服务器,是内存级的缓存。它是使用单纯的内存来进行缓存。

2. sprirng cache+redis的好处
那么Spring cache +redis的好处显而易见了。既可以很方便的缓存对象,同时用来缓存的内存的是使用redis的内存,不会消耗JVM的内存,提升了性能。当然这里Redis不是必须的,换成其他的缓存服务器一样可以,只要实现Spring的Cache类,并配置到XML里面就行了。

下面开始整合cache+redis
1.在spring-mvc.xml中加入配置

<!--开启缓存注解-->
    <cache:annotation-driven cache-manager="cacheManager"/>
    <!-- 定义缓存管理 -->
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <!--name对应的名称要在类或方法的注解中使用-->
                <bean class="com.gcol.qy.core.annotation.RedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="myCache"/>
                </bean>
            </set>
        </property>
    </bean>

几点说明:

1.com.gcol.qy.core.annotation.RedisCache 这个类是我们自己写的类 他实现了cache接口用于操作redis 如下:
2.redisTemplate 配置在spring-redis.xml 中配置好的bean 这里不作展示,不会配置redisTemplate的小伙伴去自行百度
3.<property name="name" value="myCache"/> myCache 后面使用@Cacheable会用到

package com.gcol.qy.core.annotation;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * @Author: Xuhao
 * @Date: Created in 14:29 2018/7/30
 */
public class RedisCache implements Cache {

    private RedisTemplate<String, Object> redisTemplate;
    private String name;
    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return this.name;
    }

    @Override
    public Object getNativeCache() {
        // TODO Auto-generated method stub
        return this.redisTemplate;
    }

    @Override
    public ValueWrapper get(Object key) {
        // TODO Auto-generated method stub
        System.out.println("get key");
        final String keyf = key.toString();
        Object object = null;
        object = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);
            }
        });
        return (object != null ? new SimpleValueWrapper(object) : null);
    }

    @Override
    public <T> T get(Object key, Class<T> type) {
        return null;
    }

    @Override
    public void put(Object key, Object value) {
        // TODO Auto-generated method stub
        System.out.println("put key");
        final String keyf = key.toString();
        final Object valuef = value;
        final long liveTime = 86400;
        redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
    }

    private byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }

    private Object toObject(byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return obj;
    }

    @Override
    public void evict(Object key) {
        // TODO Auto-generated method stub
        System.out.println("del key");
        final String keyf = key.toString();
        redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                return connection.del(keyf.getBytes());
            }
        });
    }

    @Override
    public void clear() {
        // TODO Auto-generated method stub
        System.out.println("clear key");
        redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                connection.flushDb();
                return "ok";
            }
        });
    }
}

测试Dao

@Override
@Cacheable(value = "myCache",key = "#openid")
public List<Object> findListCDKeyByOpenid(String openid) {
    Session session = super.getSession();
    String sql ="SELECT " +
                    "pri.cd_key as cdKey, " +
                    "war.award_name as awardName," +
                    "war.award_content as awardContent " +
                " FROM wechat_test_prizes pri " +
                " JOIN " +
                " wechat_test_awards war on(pri.award_id=war.id)" +
                " WHERE " +
                    "pri.id in (" +
                        " SELECT prize_id FROM wechat_user_lottery_record" +
                        " WHERE openid =:openid and Activity_code = 'CHILDFQ_QUIZ'" +
                    ");";
    SQLQuery sqlQuery = session.createSQLQuery(sql);
    sqlQuery.setParameter("openid",openid);
    sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

    return sqlQuery.list();
}

第一次调用如下:
这里写图片描述
第二次如下:没执行sql 直接从redis里获取的
这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_38362455/article/details/81287489