30.Spring-Boot或Spring Java Configuration中如何Spring-Data-Redis以及序列化方式

更多细节见https://blog.csdn.net/niugang0920/article/details/81530492  

   Spring框架是领先的全栈Java/JEE应用程序框架。它通过使用依赖注入、AOP和可移植的服务抽象来支持轻量级容器和非侵入性编程模型。
   NoSQL存储系统为水平可扩展性和速度提供了传统RDBMS的替代方案。在实现方面,键值存储代表了NoSQL空间中最大(也是最老的)成员之一。

    Spring Data Redis (SDR)框架通过Spring优秀的基础设施支持消除了与存储进行交互所需的冗余任务和样板代码,从而使编写使用Redis键值存储的Spring应用程序变得容易。

   注意:Spring Data Redis 2.x需要Java 8以上jdk版本,spring4.3.17以上版本支持,Redis需要2.6+版本支持。具体对应版本可参考官方文档https://docs.spring.io/spring-data/redis/docs/

 

  •     学习Spring 

    Spring Data使用Spring框架的核心功能,如IoC容器、资源抽象和AOP基础设施。虽然了解Spring api并不重要,但是理解它们背后的概念很重要。至少,IoC背后的想法应该是熟悉的。也就是说,你对Spring的了解越多,你就能越快地熟悉Spring Data.

 

  • 学习NoSQL和关键值存储

     NoSQL卷了存储世界。它是一个包含大量解决方案、术语和模式的庞大领域(更糟糕的是,即使术语本身也有多种含义)。虽然其中一些原则是通用的,但在某种程度上熟悉SDR支持的存储非常重要。了解这些解决方案的最好方法是阅读它们的文档并遵循它们的示例。通常不需要超过5到10分钟就能完成,而且,如果你来自一个只有眼球的背景,很多时候,这些练习都可以让你大开眼界。

 

  • 通过RedisTemplate处理对象

        大多数用户可能使用RedisTemplate以及它的coresponding包org.springframe.data.redis.core。
模板实际上是Redis模块的中心类,因为它有丰富的特性集。模板提供了Redis交互的高级抽象。虽然RedisConnection提供了接受和返回二进制值(字节数组)的低级方法,但是模板负责序列化和连接管理,使用户不必处理这些细节。

       RedisTemplate的大部分操作都使用基于java的序列化器。这意味着模板编写或读取的任何对象都通过Java进行序列化和反序列化。您可以在模板上更改序列化机制,Redis模块提供了几个实现,这些实现在org.springframework.data.redis.serializer序列化程序包。您还可以将任何序列化器设置为null,并通过将enableDefaultSerializer属性设置为false,对原始字节数组使用RedisTemplate。注意,模板要求所有键都是非空的。但是,只要底层序列化器接受值,值就可以为空。

    此外,该模板还提供了操作视图(从Redis命令引用中进行分组),提供了针对特定类型或特定键(通过KeyBound接口)工作的丰富的泛型接口。

 

InterfaceDescription

Key Type Operations 【Key的操作类型】

GeoOperations

Redis geospatial operations, such as GEOADDGEORADIUS,…​(经纬度的操作,在Redis2.8+之后开始支持)

HashOperations

Redis hash operations(对Hash数据结构的支持)

HyperLogLogOperations

Redis HyperLogLog operations, such as PFADDPFCOUNT,…​

ListOperations

Redis list operations   (对List集合的支持)

SetOperations

Redis set operations     (对Set集合的支持)

ValueOperations

Redis string (or value) operations  (对String数据类型的支持)

ZSetOperations

Redis zset (or sorted set) operations     (对有序集合的支持)

 

 

Key Bound Operations

BoundGeoOperations

Redis key bound geospatial operations

BoundHashOperations

Redis hash key bound operations

BoundKeyOperations

Redis key bound operations

BoundListOperations

Redis list key bound operations

BoundSetOperations

Redis set key bound operations

BoundValueOperations

Redis string (or value) key bound operations

BoundZSetOperations

Redis zset (or sorted set) key bound operations

BoundHashOperations

Redis hash key bound operations

BoundGeoOperations

Redis key bound geospatial operations.

  • 具体演示,SpringBoot中,SpringJava配置同理

pom.xml

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>

 

application.properties

#redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.pool.max-idle=3
spring.redis.pool.max-active=20

 

RedisConfig.java

package org.niugang.config;

import org.niugang.mq.MessageDelegate;
import org.niugang.mq.MessageDelegateImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

import redis.clients.jedis.JedisPoolConfig;

/**
 * 
 * @Description:redis配置相关类
 * @Project:boot-sis
 * @File:RedisConfig.java
 * @Package:org.niugang.config
 * @Date:2018年7月2日上午9:32:36
 * @author:niugang
 * @Copyright (c) 2018, 863263957@qq.com All Rights Reserved.
 *
 */
@Configuration
public class RedisConfig {
    @Value("${spring.redis.host}")
    public String host;
    @Value("${spring.redis.port}")
    public int port;
    @Value("${spring.redis.pool.max-idle}")
    public int maxIdle;
    @Value("${spring.redis.pool.max-active}")
    public int maxActive;

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setHostName(host);
        jedisConnectionFactory.setPort(port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisConnectionFactory.setPoolConfig(jedisPoolConfig);
        return jedisConnectionFactory;
    }

    // 默认用的是用JdkSerializationRedisSerializer进行序列化的
    @Bean
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        // 注入数据源
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        // key-value结构序列化数据结构
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash数据结构序列化方式,必须这样否则存hash 就是基于jdk序列化的
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        // 启用默认序列化方式
        redisTemplate.setEnableDefaultSerializer(true);
        redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);

        /// redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate() {
        return new StringRedisTemplate(jedisConnectionFactory());
    }
}

 

单元测试

package org.niugang.test;
import java.util.Date;
import java.util.Map;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.niugang.menu.entity.MenuEntity;
import org.niugang.user.entity.UserEntity;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.hash.HashMapper;
import org.springframework.data.redis.hash.Jackson2HashMapper;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 
 * @author spring-data-redis
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {

    //hash操作
    @Resource(name = "redisTemplate")
    HashOperations<String, String, Object> opsForHash;
    
    //list操作操作
    @Resource(name = "redisTemplate")
    ListOperations<String, Object> listOperations;
        /**
     * 要对对象进行json序列化,必须提前设置序列化方式
     */
    private HashMapper<Object, String, Object> mapper = new Jackson2HashMapper(false);

    @Test
    public void save() {
        MenuEntity menuEntity = new MenuEntity();
        menuEntity.setCreateTime(new Date());
        menuEntity.setCreator("admin");
        menuEntity.setDeleteFlag("1");
        menuEntity.setIsChildren("0");
        menuEntity.setName("员工考勤");
        menuEntity.setUrl("/person/list");
        menuEntity.setParent("4028aa9c645e5a8101645e5ac3500000");
        // writeHash("test1", menuEntity);
    }
@Test
    public void save2() {
        UserEntity userEntity = new UserEntity();
        userEntity.setAccount("34343");
        userEntity.setCreateTime(new Date());
        userEntity.setName("张三");
        writeHash("test2", userEntity);
    }
    
    @Test
    public void save3() {
        listOperations.leftPushAll("list1", "考虑空间来看","都是度搜你就手动","是的激励酒叟","炯炯发的");
    }

    @Test
    public void find() {
        loadHash("test2");
    }

    public void writeHash(String key, UserEntity person) {

        Map<String, Object> hash = mapper.toHash(person);
        opsForHash.putAll(key, hash);
    }

    public UserEntity loadHash(String key) {
        Map<String, Object> entries = opsForHash.entries(key);
        UserEntity fromHash = (UserEntity) mapper.fromHash(entries);
        return fromHash;
    }

}

 

 

 微信公众号

 

 

posted @ 2020-01-14 17:01  盲目的拾荒者  阅读(359)  评论(0编辑  收藏  举报