Redis初学及与Spring集成小结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis初学及与Spring集成小结相关的知识,希望对你有一定的参考价值。

Redis初学及与Spring集成小结
1.redis是干什么的?
    redis是一种key-value内存数据库。在技术日新月异的发展环境下,客户的访问需求也在逐渐增长,物理数据库的压力也越来越大,由此redis也应运而生。
    redis常用的方式是将redis作为缓存数据库,减小物理数据库的访问压力;

2.redis常用数据结构:
    a.strings:
        set key value;设置key-value值
        get key;获取key的value值
        redis...method(redis中的一些方法) key;redis的方法修改key的value值
    b.lists:类似于java的链表
        lpush mylist value;在list最左加入value
        rpush myllist value;在list最右加入value
        lrange mylist start end;获取list从start到end的value值,左边的第一个元素下标是0,右边的第一个元素的下标是-1
    c.sets:类似于java中的set
        sadd myset value:向myset中添加值
        smembers myset:获取myset中的所有项
        sismember myset value;查看value是否存在于myset中,存在则返回1,不存在则发挥0
        sunion set1 set2;合并两个set
    d.zsets:类似于java的list
        zadd myzset 1 baidu.com:设置myzset中下标为1的元素值为baidu.com
        zrange myzset 0 -1;获取myzset从0到-1的value值
    f.hashes:类似于java的Map
        HMSET user:001 username antirez password P1pp0 age 34;设置user:001的各项key-value值
        HGETALL user:001;获取user:001的各项key-value值
        HSET user:001 password 12345;修改user:001的password值
    上述五种结构,我们一般的spring集成的时候往往采用的是第一种,其余四种暂时还没涉及

3.与spring的集成
    <!-- jedis 配置可以理解为redis连接池 -->  
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >
         <property name="maxIdle" value="${redis.maxIdle}" />  
         <property name="maxWaitMillis" value="${redis.maxWait}" />  
         <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
    </bean >  
    <!-- redis服务器中心 可以理解为redis工厂-->  
    <bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >  
         <property name="poolConfig" ref="poolConfig" />  
         <property name="port" value="${redis.port}" />  
         <property name="hostName" value="${redis.host}" />      
         <property name="password" value="${redis.password}" />  
         <property name="timeout" value="${redis.timeout}" ></property>  
    </bean >  
    <!-- redis操作的模板,属性有redis的工厂以及key-value的序列化类型 -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >  
         <property name="connectionFactory" ref="connectionFactory" />  
         <property name="keySerializer" >  
             <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
         </property>  
         <property name="valueSerializer" >  
             <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />  
         </property>  
    </bean >  
    
    <cache:annotation-driven cache-manager="cacheManager" />  
  
    <!-- spring自己的换管理器,这里定义了缓存位置名称 ,即注解中的value,可以在service实现类中使用@CacheConfig、@Cacheable、@CachePut、@CacheEvict注解,下面配置的mvc是缓存名-->  
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
        <property name="caches">  
            <set>  
                <bean class="util.redis.RedisCache">  
                    <property name="redisTemplate" ref="redisTemplate" />  
                    <property name="name" value="mvc"/>  
                </bean>
            </set>  
        </property>  
    </bean>  
4.RedisCache类
    package util.redis;  
  
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.concurrent.Callable;

    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;


    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) {
            final String keyf = key.toString();
            Object object = null;
            object = redisTemplate.execute(new RedisCallback<Object>() {
                public Object doInRedis(RedisConnection connection)
                        throws DataAccessException {

                    byte[] key = keyf.getBytes();
                    byte[] value = connection.get(key);
                    if (value == null) {
                        return null;
                    }
                    System.out.println(toObject(value));
                    return toObject(value);

                }
            });
            return (object != null ? new SimpleValueWrapper(object) : null);
        }

        @Override
        public void put(Object key, Object value) {
            final String keyf = key.toString();
            final Object valuef = value;
            final long liveTime = 86400;

            redisTemplate.execute(new RedisCallback<Long>() {
                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);
                    }
                    System.out.println("key-name:"+keyf+",key-bytes:"+keyf.getBytes());
                    System.out.println("插入缓存");
                    return 1L;
                }
            });
        }

        /**
         * 描述 : <Object转byte[]>. <br>
         * <p>
         * <使用方法说明>
         * </p>
         * 
         * @param obj
         * @return
         */
        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;
        }

        /**
         * 描述 : <byte[]转Object>. <br>
         * <p>
         * <使用方法说明>
         * </p>
         * 
         * @param bytes
         * @return
         */
        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
            final String keyf = key.toString();
            redisTemplate.execute(new RedisCallback<Long>() {
                public Long doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    System.out.println("key-name:"+keyf+",key-bytes:"+keyf.getBytes());
                    return connection.del(keyf.getBytes());
                }
            });
        }

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

        @Override
        public <T> T get(Object key, Class<T> type) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public <T> T get(Object key, Callable<T> valueLoader) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ValueWrapper putIfAbsent(Object key, Object value) {
            // TODO Auto-generated method stub
            return null;
        }

    }
5.spring实现类使用redis注解,备注:demo只是示范,实际项目按需配置
    @Service("userService")
    //mvc是上面的配置文件中配置的RedisCache的name的value值,意为缓存存放的名称
    @CacheConfig(cacheNames="mvc")
    public class UserServiceImpl implements UserService{
    
        @Autowired
        private UserDao userDao;
        
        @Override
        //添加缓存,key取得param的name的toString值
        @Cacheable(key="#param[‘name‘].toString()")
        public User get(Map<String, Object> param) {
            System.out.println("有个屁的缓存");
            return userDao.get(param);
        }

        //将方法的返回结果重新设置到缓存中,无论缓存中是否存在,相当于缓存的更新
        @CachePut()
        public User update(User user) {
            return user;
        }
        
        //清除缓存,key与@Cacheable中的配置是一样的
        @CacheEvict(key="#param[‘name‘].toString()")
        public int delete(Map<String, Object> param) {
            return 1;
        }
    }
  

 

以上是关于Redis初学及与Spring集成小结的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 整合 redis

Spring Boot中使用Redis小结

spring-data-redis,jedis和redis主从集成和遇到的问题

SpringBoot学习小结

Spring + Jedis集成Redis

Sonar6.0应用之二:Sonar Web界面配置及与RunnerScanner集成进行命令行代码分析