• jedis访问redis学习笔记


            最近在学习redis,在网上查了些文章,利用他人已有的知识,总结写下了这篇文章,大部分内容还是引用别人的文章内容。经过测试发现spring-data-redis现在有的版本只能支持reids 2.6和2.8版本,更高版本尚未支持。还是直接使用jedis比较灵活。

         redis

    • redis安装

                 redis的安装过程在以前的博文中已经详细介绍  linux下安装redis并自启动

    • jedis

                 jedis下载地址:https://github.com/xetorthio/jedis
                 jedis社区地址:https://groups.google.com/forum/#!forum/jedis_redis


         最简单的Jedis访问redis

    • jedis官方示例

                  1、键值读取

           Jedis jedis = new Jedis("redis服务器ip地址", 6379);
           jedis.set("foo", "123456");
           String value = jedis.get("foo");				
           System.out.println("____________value="+value);

                  2、集群读取

           Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
           //Jedis Cluster will attempt to discover cluster nodes automatically
           jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
           JedisCluster jc = new JedisCluster(jedisClusterNodes);
           jc.set("foo", "bar");
           String value = jc.get("foo");

         jedis 池和sharding基本示例


           redis的基本配置信息

            将以下内容放在redis.properties或者文件中,后面有关的.properties文件的内容都跟下面一样的内容。

        redis.host=192.168.1.100
        redis.port=6379
        redis.pass=123456
        redis.default.db=0
        redis.timeout=100000//客户端超时时间单位是毫秒  
        redis.maxActive=300// 最大连接数  
        redis.maxIdle=100//最大空闲数
        redis.maxWait=1000//最大建立连接等待时间
        redis.testOnBorrow=true
        redis.testOnReturn=true;
    

         java读取配置文件

        ResourceBundle bundle = ResourceBundle.getBundle("redis");
        if (bundle == null) {
            throw new IllegalArgumentException(
                    "[redis.properties] is not found!");
        }
    

         redis池

            jedisc池需要commons-pool.jar的支持。

    • 池对象的获取与回收

                  在没有使用spring-data-redis的情况下,需要手工获取池对象,并在使用完毕后放回对象池中。

                  在使用redis池,需要通过以下代码方式从pool中获取资源。

           jedisPool.getResource()

                  资源使用完毕后需要放入pool中

          jedisPool.returnResource(jedis);

                  具体的示例代码

        public class MyJedisPool {
            // jedis池
            private static JedisPool pool;
            
            // 静态代码初始化池配置
            static {
               // 加载redis配置文件
               ResourceBundle bundle = ResourceBundle.getBundle("redis");
    
               if (bundle == null) {
                   throw new IllegalArgumentException("[redis.properties] is not found!");
               }
    
               // 创建jedis池配置实例
               JedisPoolConfig config = new JedisPoolConfig();
    
               // 设置池配置项值
               config.setMaxActive(Integer.valueOf(bundle.getString("redis.pool.maxActive")));
               config.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle")));
               config.setMaxWait(Long.valueOf(bundle.getString("redis.pool.maxWait")));
               config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));
               config.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn")));
               
              //根据配置实例化jedis池
               pool = new JedisPool(config, bundle.getString("redis.ip"), Integer.valueOf(bundle.getString("redis.port")));
            }
    
            /**
             * 测试jedis池方法
             */
            public static void test1() {
               // 从jedis池中获取一个jedis实例
               Jedis jedis = pool.getResource();
    
               // 获取jedis实例后可以对redis服务进行一系列的操作
               jedis.set("name", "xmong");
               System.out.println(jedis.get("name"));
    
               jedis.del("name");
               System.out.println(jedis.exists("name"));
    
               // 释放对象池,即获取jedis实例使用后要将对象还回去
               pool.returnResource(jedis);
            }
        }
    

           redis分布式

    • 分布式配置信息
        #redis1服务器ip #  
        Redis1.ip=172.30.5.113 
    
        #redis2服务器ip #  
        Redis2.ip=172.30.5.117 
    
        #redis服务器端口号# 
        redis.port=6379  
    • 分布式读取方法
        public class MyJedisPool {
            // jedis池
            private static JedisPool pool;
    
            // shardedJedis池
            private static ShardedJedisPool shardPool;
    
            // 静态代码初始化池配置
    
            static {
               // 加载redis配置文件
               ResourceBundle bundle = ResourceBundle.getBundle("redis");
    
               if (bundle == null) {
                   throw new IllegalArgumentException("[redis.properties] is not found!");
               }
    
               // 创建jedis池配置实例
               JedisPoolConfig config = new JedisPoolConfig();
    
               // 设置池配置项值
               config.setMaxActive(Integer.valueOf(bundle.getString("redis.pool.maxActive")));
               config.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle")));
               config.setMaxWait(Long.valueOf(bundle.getString("redis.pool.maxWait")));
               config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));
               config.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn")));
    
               // 根据配置实例化jedis池
               // pool = new JedisPool(config, bundle.getString("redis.ip"),
               // Integer.valueOf(bundle.getString("redis.port")));
    
               // 创建多个redis共享服务
               JedisShardInfo jedisShardInfo1 = new JedisShardInfo(bundle.getString("redis1.ip"), Integer.valueOf(bundle.getString("redis.port")));
               JedisShardInfo jedisShardInfo2 = new JedisShardInfo(bundle.getString("redis2.ip"), Integer.valueOf(bundle.getString("redis.port")));
    
               List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
               list.add(jedisShardInfo1);
               list.add(jedisShardInfo2);
    
               // 根据配置文件,创建shared池实例
               shardPool = new ShardedJedisPool(config, list);
            }
    
            /**
             * 测试jedis池方法
             */
            public static void test1() {
               // 从jedis池中获取一个jedis实例
               Jedis jedis = pool.getResource();
    
               // 获取jedis实例后可以对redis服务进行一系列的操作
               jedis.set("name", "xmong");
               System.out.println(jedis.get("name"));
    
               jedis.del("name");
               System.out.println(jedis.exists("name"));
    
               // 释放对象池,即获取jedis实例使用后要将对象还回去
               pool.returnResource(jedis);
            }
    
            /**
             * 测试shardedJedis池方法
             */
            public static void test2() {
               // 从shard池中获取shardJedis实例
               ShardedJedis shardJedis = shardPool.getResource();
         
               // 向redis服务插入两个key-value对象
               shardJedis.set("aaa", "xmong_aaa");
               System.out.println(shardJedis.get("aaa"));
    
               shardJedis.set("zzz", "xmong_zzz");
               System.out.println(shardJedis.get("zzz"));
    
               // 释放资源
               shardPool.returnResource(shardJedis);
            }
    
         
    
            public static void main(String[] args) {
               // test1();//执行test1方法
               test2();// 执行test2方法
            }
        }

         spinrg 整合redis

          spring结合redis配置连接池

    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxActive" value="32"></property>
    		<property name="maxIdle" value="6"></property>
    		<property name="maxWait" value="15000"></property>
    		<property name="minEvictableIdleTimeMillis" value="300000"></property>
    		<property name="numTestsPerEvictionRun" value="3"></property>
    		<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
    		<property name="whenExhaustedAction" value="1"></property>
    	</bean>
    	<bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy">
    		<!-- config -->
    		<constructor-arg ref="jedisPoolConfig"></constructor-arg>
    		<!-- host -->
    		<constructor-arg value="127.0.0.1"></constructor-arg>
    		<!-- port -->
    		<constructor-arg value="6379"></constructor-arg>
    		<!-- timeout -->
    		<constructor-arg value="15000"></constructor-arg>
    		<!-- password -->
    		<constructor-arg value="0123456"></constructor-arg>
    		<!-- database index -->
    		<constructor-arg value="12"></constructor-arg>		
    	</bean>

           测试类

    public static void main(String[] args) {
    	//resources/beans.xml
    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
    	JedisPool jedisPool = (JedisPool)context.getBean("jedisPool");
    	Jedis client = jedisPool.getResource();
    	try{
    		client.select(0);
    		client.set("k1", "v1");
    		System.out.println(client.get("k1"));
    	}catch(Exception e){
    		e.printStackTrace();
    	}finally{
    		jedisPool.returnResource(client);//must be
    	}
    }

           new ClassPathXmlApplicationContext("classpath:beans.xml");是直接读取beans.xml文件,因此需要将上面的配置内容放在beans.xml中,来获取bean对象实例。 

          spring 结合redis sharding

        <context:property-placeholder location="classpath:redis.properties" />  
        <context:component-scan base-package="com.d.work.main">
        </context:component-scan>
            <context:component-scan base-package="com.d.work.redis">
        </context:component-scan>
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxActive" value="50" />
            <property name="maxIdle" value="8" />
            <property name="maxWait" value="1000" />
            <property name="testOnBorrow" value="true"/>
            <property name="testOnReturn" value="true"/>
            <!-- <property name="testWhileIdle" value="true"/> -->
        </bean>
    
        <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool"  scope="singleton">
            <constructor-arg index="0" ref="jedisPoolConfig" />
            <constructor-arg index="1">
                <list>
                    <bean class="redis.clients.jedis.JedisShardInfo">
                        <constructor-arg name="host" value="${redis.host}" />
                        <constructor-arg name="port" value="${redis.port}" />
                        <constructor-arg name="timeout" value="${redis.timeout}" />
                        <constructor-arg name="weight" value="1" />
                    </bean>
                </list>
            </constructor-arg>
        </bean>

         Spring-data-redis

            spring 提供jsmTemplement,jdbcTemplement,redisTemplement等类似模板。spring 通过context:property-placeholder实现导入配置文件,context:property-placeholder 标签用来导入properties文件。从而替换${redis.maxIdle}这样的变量。要使用spring-data-redis,需要下载spring-data-redis-1.5.1.RELEASE.jar

           spring-data-redis针对redis提供了以下的特性

    • 连接池自动管理

                  提供了一个高度封装的“RedisTemplate”类

    • 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口

                      ValueOperations:简单K-V操作
                      SetOperations:set类型数据操作
                      ZSetOperations:zset类型数据操作
                      HashOperations:针对map类型的数据操作
                      ListOperations:针对list类型的数据操作

    •  提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即BoundKeyOperations:

                    BoundValueOperations
                    BoundSetOperations
                    BoundListOperations
                    BoundSetOperations
                    BoundHashOperations

    •  将事务操作封装,有容器控制。
    • 针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)

                   JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。
                    StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。
                    JacksonJsonRedisSerializer:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】
                    OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】
                    针对“序列化和发序列化”中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的策略,原则上,我们可以将数据存储为任何格式以便应用程序存取和解析(其中应用包括app,hadoop等其他工具),不过在设计时仍然不推荐直接使用“JacksonJsonRedisSerializer”和“OxmSerializer”,因为无论是json还是xml,他们本身仍然是String。
                    如果你的数据需要被第三方工具解析,那么数据应该使用StringRedisSerializer而不是JdkSerializationRedisSerializer。
                    如果你的数据格式必须为json或者xml,那么在编程级别,在redisTemplate配置中仍然使用StringRedisSerializer,在存储之前或者读取之后,使用“SerializationUtils”工具转换转换成json或者xml,请参见下文实例。

    • 基于设计模式,和JMS开发思路,将pub/sub的API设计进行了封装,使开发更加便捷。
    • spring-data-redis中,并没有对sharding提供良好的封装,如果你的架构是基于sharding,那么你需要自己去实现,这也是sdr和jedis相比,唯一缺少的特性。        

            spinrg-data-redis配置与调用

                示例一

        <bean id="propertyConfigurerRedis" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
                <property name="order" value="1" />  
                <property name="ignoreUnresolvablePlaceholders" value="true" />  
                <property name="locations">  
                    <list>  
                        <value>classpath:config/redis-manager-config.properties</value>  
                    </list>  
                </property>  
            </bean>  
              
                <!-- jedis pool配置 -->  
            <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
                <property name="maxActive" value="${redis.maxActive}" />  
                <property name="maxIdle" value="${redis.maxIdle}" />  
                <property name="maxWait" value="${redis.maxWait}" />  
                <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
            </bean>  
          
            <!-- spring data redis -->  
            <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
                <property name="usePool" value="true"></property>  
                <property name="hostName" value="${redis.host}" />  
                <property name="port" value="${redis.port}" />  
                <property name="password" value="${redis.pass}" />  
                <property name="timeout" value="${redis.timeout}" />  
                <property name="database" value="${redis.default.db}"></property>  
                <constructor-arg index="0" ref="jedisPoolConfig" />  
            </bean>  
              
            <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
                <property name="connectionFactory" ref="jedisConnectionFactory" />  
            </bean>  
       
    
    public class RedisBase {  
      
        private StringRedisTemplate template;  
      
        /** 
         * @return the template 
         */  
        public StringRedisTemplate getTemplate() {  
            return template;  
        }  
      
        /** 
         * @param template the template to set 
         */  
        public void setTemplate(StringRedisTemplate template) {  
            this.template = template;  
        }  
      
    } 

               示例二

    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxActive" value="32"></property>
    		<property name="maxIdle" value="6"></property>
    		<property name="maxWait" value="15000"></property>
    		<property name="minEvictableIdleTimeMillis" value="300000"></property>
    		<property name="numTestsPerEvictionRun" value="3"></property>
    		<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
    		<property name="whenExhaustedAction" value="1"></property>
    	</bean>
    	<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    		<property name="poolConfig" ref="jedisPoolConfig"></property>
    		<property name="hostName" value="127.0.0.1"></property>
    		<property name="port" value="6379"></property>
    		<property name="password" value="0123456"></property>
    		<property name="timeout" value="15000"></property>
    		<property name="usePool" value="true"></property>
    	</bean>
    	<bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    		<property name="connectionFactory" ref="jedisConnectionFactory"></property>
    		<property name="keySerializer">
    			<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    		</property>
    		<property name="valueSerializer">
    			<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
    		</property>
    	</bean>
    public class SpringDataRedisTestMain {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-redis-beans.xml");
    		RedisTemplate redisTemplate = (RedisTemplate)context.getBean("jedisTemplate");
    		//其中key采取了StringRedisSerializer
    		//其中value采取JdkSerializationRedisSerializer
    		ValueOperations<String, User> valueOper = redisTemplate.opsForValue();
    		User u1 = new User("zhangsan",12);
    		User u2 = new User("lisi",25);
    		valueOper.set("u:u1", u1);
    		valueOper.set("u:u2", u2);
    		System.out.println(valueOper.get("u:u1").getName());
    		System.out.println(valueOper.get("u:u2").getName());
    	}
    	
    	/**
    	 * 如果使用jdk序列化方式,bean必须实现Serializable,且提供getter/setter方法
    	 * @author qing
    	 *
    	 */
    	static class User implements Serializable{
    		
    		/**
    		 * 
    		 */
    		private static final long serialVersionUID = -3766780183428993793L;
    		private String name;
    		private Date created;
    		private int age;
    		public User(){}
    		public User(String name,int age){
    			this.name = name;
    			this.age = age;
    			this.created = new Date();
    		}
    		public String getName() {
    			return name;
    		}
    		public void setName(String name) {
    			this.name = name;
    		}
    		public Date getCreated() {
    			return created;
    		}
    		public void setCreated(Date created) {
    			this.created = created;
    		}
    		public int getAge() {
    			return age;
    		}
    		public void setAge(int age) {
    			this.age = age;
    		}
    		
    	}
    
    }

     
               如果你使用过jedisPool连接池,在数据操作之前,你需要pool.getResource()即从连接池中获取“链接资源”(Jedis),在操作之后,你需要(必须)调用pool.returnResource()将资源归还个连接池。但是,spring-data-redis中,我们似乎并没有直接操作pool,那么spring是如何做到pool管理的呢??一句话:spring的“看门绝技”--callback。   

                public <T> T execute(RedisCallback<T> action):这个方法是redisTemplate中执行操作的底层方法,任何基于redisTemplate之上的调用(比如,valueOperations)最终都会被封装成RedisCallback,redisTemplate在execute方法中将会直接使用jedis客户端API进行与server通信,而且在如果使用了连接池,则会在操作之后执行returnSource。

                  java读取bean方式

                 方式一

    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-redis-beans.xml");
    	RedisTemplate redisTemplate = (RedisTemplate)context.getBean("jedisTemplate");

                 方式二

            ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:setup/applicationContext.xml"); 
    	cachedClient = (MemCachedClient)ctx.getBean("memcachedClient"); 

              Spring-data-redis: pub/sub消息订阅

                  redis可以用来做消息订阅操作。

                  第一步配置

    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxActive" value="32"></property>
    		<property name="maxIdle" value="6"></property>
    		<property name="maxWait" value="15000"></property>
    		<property name="minEvictableIdleTimeMillis" value="300000"></property>
    		<property name="numTestsPerEvictionRun" value="3"></property>
    		<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
    		<property name="whenExhaustedAction" value="1"></property>
    	</bean>
    	<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    		<property name="poolConfig" ref="jedisPoolConfig"></property>
    		<property name="hostName" value="127.0.0.1"></property>
    		<property name="port" value="6379"></property>
    		<property name="password" value="0123456"></property>
    		<property name="timeout" value="15000"></property>
    		<property name="usePool" value="true"></property>
    	</bean>
    	<bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    		<property name="connectionFactory" ref="jedisConnectionFactory"></property>
    		<property name="defaultSerializer">
    			<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    		</property>
    	</bean>
    	
    	<bean id="topcMessageListener" class="com.sample.redis.sdr.TopicMessageListener">
    		<property name="redisTemplate" ref="jedisTemplate"></property>
    	</bean>
    	<bean id="topicContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy">
    		<property name="connectionFactory" ref="jedisConnectionFactory"/>
    		<property name="taskExecutor"><!-- 此处有个奇怪的问题,无法正确使用其他类型的Executor -->
    			<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
    				<property name="poolSize" value="3"></property>
    			</bean>
    		</property>
    		<property name="messageListeners">
    			<map>
    				<entry key-ref="topcMessageListener">
    					<bean class="org.springframework.data.redis.listener.ChannelTopic">
    						<constructor-arg value="user:topic"/>
    					</bean>
    				</entry>
    			</map>
    		</property>
    	</bean>

                 第二部:发布消息

    String channel = "user:topic";
    //其中channel必须为string,而且“序列化”策略也是StringSerializer
    //消息内容,将会根据配置文件中指定的valueSerializer进行序列化
    //本例中,默认全部采用StringSerializer
    //那么在消息的subscribe端也要对“发序列化”保持一致。
    redisTemplate.convertAndSend(channel, "from app 1");


                 第三部:消息接收

    public class TopicMessageListener implements MessageListener {
    
    	private RedisTemplate redisTemplate;
    	
    	public void setRedisTemplate(RedisTemplate redisTemplate) {
    		this.redisTemplate = redisTemplate;
    	}
    
    	@Override
    	public void onMessage(Message message, byte[] pattern) {
    		byte[] body = message.getBody();//请使用valueSerializer
    		byte[] channel = message.getChannel();
    		//请参考配置文件,本例中key,value的序列化方式均为string。
    		//其中key必须为stringSerializer。和redisTemplate.convertAndSend对应
    		String itemValue = (String)redisTemplate.getValueSerializer().deserialize(body);
    		String topic = (String)redisTemplate.getStringSerializer().deserialize(channel);
    		//...
    	}
    }

               spring-data-redis 事物处理

                   以下示例显示spring-data-redis实现事物处理,并通过回调方法实现返回数据

        //execute a transaction
        List<Object> txResults = redisTemplate.execute(new SessionCallback<List<Object>>() {
          public List<Object> execute(RedisOperations operations) throws DataAccessException {
            operations.multi();
            operations.opsForSet().add("key", "value1");
    
            // This will contain the results of all ops in the transaction
            return operations.exec();
          }
        });
        System.out.println("Number of items added to set: " + txResults.get(0));
    


       

         Spring-data-redis: serializer实例

    sdr提供了4种内置的serializer:

            1、JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储

            2、StringRedisSerializer:字符串编码,数据以string存储

           3、JacksonJsonRedisSerializer:json格式存储

           4、OxmSerializer:xml格式存储

        其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,其中“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。

        RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:

        1) keySerializer :对于普通K-V操作时,key采取的序列化策略
        2) valueSerializer:value采取的序列化策略
        3) hashKeySerializer: 在hash数据结构中,hash-key的序列化策略
        4) hashValueSerializer:hash-value的序列化策略

        无论如何,建议key/hashKey采用StringRedisSerializer。

           配置JdkSerializationRedisSerializer/StringRedisSerializer

    <bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    	<property name="connectionFactory" ref="jedisConnectionFactory"></property>
    	<property name="keySerializer">
    		<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    	</property>
    	<property name="hashKeySerializer">
    		<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    	</property>
    	<property name="valueSerializer">
    		<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
    	</property>
    	<property name="hashValueSerializer">
    		<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
    	</property>
    </bean>
    ValueOperations<String, User> valueOper = redisTemplate.opsForValue();
    User user = new User("zhangsan",12);
    valueOper.set("user:1", user);
    System.out.println(valueOper.get("user:1").getName());

           题外话

               spring framework4.X.X版本与spring framework3.X.X有些区别:

               spring framework 4.X.X需要jackjson2.0,同时 org.springframework.http.converter.json.MappingJacksonHttpMessageConverter改为 MappingJacksonHttpMessageConverter已经改为MappingJackson2HttpMessageConverter
     
                spring framework 4.X.X配置中使用
                <mvc:annotation-driven/>

                不再需要手工配置bean

    	<bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >  
    	    <property name="messageConverters">
    		  	<list>  
    		   		<ref bean="mappingJackson2HttpMessageConverter" />
    		  	</list>  
    	 	</property>  
    	</bean>
    		
    	<bean name="mappingJackson2HttpMessageConverter" 
    	      class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    	   <property name="supportedMediaTypes">  
            <list>  
                <value>text/html;charset=UTF-8</value>  
            </list>  
        	</property>       
    	</bean>


           参考资料

                http://snowolf.iteye.com/blog/1630697

                 http://my.oschina.net/gccr/blog/307725

                 http://blog.163.com/asd_wll/blog/static/210310402013654528316/

                 http://wenku.baidu.com/link?url=fuS8aw93_4_Qvv8WBgazt5eZGiDhv1Np5vCyB8qBUVdWIUxI47IaA5opzI3vwhWth7MrF1KiJn_o1aBvWmFdeNxbmbcSnyCTEd54C0iLLEC

                 http://my.oschina.net/gccr/blog/307725

                 http://shift-alt-ctrl.iteye.com/blog/1886831

                 http://www.cnblogs.com/liuling/p/2014-4-19-04.html

                 http://www.cnblogs.com/tankaixiong/p/3660075.html

                 http://blog.csdn.net/neubuffer/article/details/17003909

                 http://blog.csdn.net/liuzhigang1237/article/details/8283797
                 http://shift-alt-ctrl.iteye.com/blog/1887370
                 http://shift-alt-ctrl.iteye.com/blog/1887473
                 http://shift-alt-ctrl.iteye.com/blog/1887644
                 http://shift-alt-ctrl.iteye.com/blog/1887700
                 http://shift-alt-ctrl.iteye.com/blog/1886831
                 http://shift-alt-ctrl.iteye.com/blog/1885910

                 http://www.open-open.com/lib/view/open1385173126448.html

                 http://blog.csdn.net/A_lele123/article/details/43406547

                 http://javacrazyer.iteye.com/blog/1840161

                 http://redis.readthedocs.org/en/2.4/index.html
     

  • 相关阅读:
    性能测试工具LoadRunner11-LR之Virtual User Generator 移动app录制
    性能测试工具LoadRunner10-LR之Virtual User Generator 错误处理函数
    性能测试工具LoadRunner09-LR之Virtual User Generator 日志
    解决粘包-简单版本
    关于三级菜单
    Python学习的第二天
    CSS选择器的权重与优先规则
    keydown/keypress/keyup
    APICloud 实现 使用openFrameGroup引入页面后禁止上下滑动
    WampServer 3.0.6 服务器端配置
  • 原文地址:https://www.cnblogs.com/wala-wo/p/5119198.html
Copyright © 2020-2023  润新知