微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SpringBoot整合Redis--RedisTemplate

SpringBoot整合Redis--Redistemplate

1、导入依赖

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

2、编写配置文件

spring:
  redis:
    host: 192.168.27.132
    port: 6379
    password: lzyredis
    database: 1
    jedis:
      pool:
        max-active: 10
        max-wait: 3000
        min-idle: 5
        max-idle: 10

3、测试代码

Redistemplate.opsForXxx().操作

  • Xxx:代表要操作的数据类型【value代表操作的是string】
@SpringBoottest
class SpringbootRedisDemoApplicationTests {
    @Autowired
    private Redistemplate redistemplate;

    @Test
    public void test(){
        //setIfAbsent 就是 setnx
        Boolean absent = redistemplate.opsForValue().setIfAbsent("name", "xiaoming", 5 * 60, SECONDS);
        System.out.println("absent = " + absent);

        String name = (String) redistemplate.opsForValue().get("name");
        System.out.println("name = " + name);

    }
}

springboot整合redis测试后存储的数据

image

打印结果

image

在第一张图中发现存储的key和value前出现了一些不认识的字符,虽然在RedisDesktopManager工具上显示不是期望的格式,但在打印结果上看却是正常显示的。

这是因为使用Redistemplate来操作字符串时,在存储数据时会对key和value进行序列化操作。

序列化操作会对选择对应的序列化器来操作,如果没有指定序列化器,那么认选择是JDK序列化器

所以会出现一长串字符串。

4、Redistemplate选择序列化器的原理:

Redistemplate 继承RedisAccessor类,而该类实现了InitializingBean接口,

所以Redistemplate调用afterPropertiesSet方法

在该方法中会对操作key和value进行序列化操作,

如果指定了具体的序列化器,那么就会使用指定的序列化器,

如果没有指定具体的序列化器,则使用JDK序列化器

public void afterPropertiesSet() {
    super.afterPropertiesSet();
    boolean defaultUsed = false;
    if (this.defaultSerializer == null) {
        //没有指定的序列化器,那认序列化器就为jdk序列化器
        this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
    }

    if (this.enableDefaultSerializer) {
        if (this.keySerializer == null) {
            this.keySerializer = this.defaultSerializer;
            defaultUsed = true;
        }

        if (this.valueSerializer == null) {
            this.valueSerializer = this.defaultSerializer;
            defaultUsed = true;
        }

        if (this.hashKeySerializer == null) {
            this.hashKeySerializer = this.defaultSerializer;
            defaultUsed = true;
        }

        if (this.hashValueSerializer == null) {
            this.hashValueSerializer = this.defaultSerializer;
            defaultUsed = true;
        }
    }

    if (this.enableDefaultSerializer && defaultUsed) {
        Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
    }

    if (this.scriptExecutor == null) {
        this.scriptExecutor = new DefaultScriptExecutor(this);
    }

    this.initialized = true;
}

如果不想使用认的序列化器,可以自己指定序列化器或使用redis提供的StringRedistemplate对象

5、配置序列化器

@Configuration
public class MyRedisConfig {

    @Bean("myRedistemplate")
    public Redistemplate myRedistemplate(RedisConnectionFactory connectionFactory){
        Redistemplate myRedistemplate = new Redistemplate();
        //设置连接工厂
        myRedistemplate.setConnectionFactory(connectionFactory);

        //更换key和value的序列化器
        myRedistemplate.setKeySerializer(new StringRedisSerializer());
        myRedistemplate.setValueSerializer(new StringRedisSerializer());
        return myRedistemplate;
    }

}
  • 测试
@SpringBoottest
public class myRedistemplateTest {
    @Autowired
    private Redistemplate myRedistemplate;

    @Test
    public void myRedistemplatetest(){
        Boolean flag = myRedistemplate.opsForValue().setIfAbsent("name2", "zhangsan", 5 * 60, TimeUnit.SECONDS);
        System.out.println("flag = " + flag);

        String  name2 = (String) myRedistemplate.opsForValue().get("name2");
        System.out.println("name2 = " + name2);
    }
}

  • redistemlate加上序列化器后存储的数据
redistemlate指定序列化器后存储的数据

image

6、StringRedistemplate

6.2 StringRedistemplate分析

StringRedistemplate就相当于指定了String序列化器的Redistemplate对象

查看org.springframework.data.redis.core包下的StringRedistemplate源码:

public class StringRedistemplate extends Redistemplate<String, String> {
    public StringRedistemplate() {
        this.setKeySerializer(RedisSerializer.string());
        this.setValueSerializer(RedisSerializer.string());
        this.setHashKeySerializer(RedisSerializer.string());
        this.setHashValueSerializer(RedisSerializer.string());
    }

    public StringRedistemplate(RedisConnectionFactory connectionFactory) {
        this();
        this.setConnectionFactory(connectionFactory);
        this.afterPropertiesSet();
    }

    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
        return new DefaultStringRedisConnection(connection);
    }
}

从源码中可以看到StringRedistemplate构造函数中指定了key、value的序列化器为string序列化器

这就相当于第五点我们自定义RedisTemplate并指定string序列化器。因此我们可以直接注入使用StringRedistemplate对象

6.2 StringRedistemplate使用

@SpringBoottest
public class myRedistemplateTest {

    @Resource
    private StringRedistemplate stringRedistemplate;

    @Test
    public void test(){
        stringRedistemplate.opsForValue().set("age","123");
    }
}

StringRedistemplate使用结果

image

7、redistemplate存储对象

使用redistemplate的opsForValue可以存储对象,存储时会把对象转成字节数组来存储

@SpringBoottest
public class SaveObjectTest {
    @Autowired
    private Redistemplate redistemplate;

    @Test
    public void savetest(){
        Person person = new Person();
        person.setId(1);
        person.setName("zhangsan");
        person.setAge(20);
		//使用redistemplate的opsForValue可以存储对象,存储时会把对象转成字节数组来存储
        redistemplate.opsForValue().set("person"+person.getId(),person);

        Person person1 = (Person) redistemplate.opsForValue().get("person1");
        System.out.println("person1 = " + person1);
    }
}

相比较与jedis存储对象,更加方便,去掉了我们自己自定义的将对象转为字符串或者字符数组的过程。redistemplate会将对象转为字节数组来存储。

运行结果:

redistemplate存储对象

image

8、redistemplate管道操作

  • 不使用管道存储10000个对象,用时约7158ms
@SpringBoottest
public class SaveObjectTest {
    @Autowired
    private Redistemplate redistemplate;

    @Test
    public void savetest(){
        Person person = new Person();
        person.setId(1);
        person.setName("zhangsan");
        person.setAge(20);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            redistemplate.opsForValue().set("person" + person.getId()+i, person);
        }
        System.out.println(System.currentTimeMillis()-start); //用时7158ms
    }
}
  • 使用管道存储10000个对象
@SpringBoottest
public class SaveObjectTest {
    @Autowired
    private Redistemplate redistemplate;

   @Test
    public void pipelinetest() {
        long start = System.currentTimeMillis();
        redistemplate.executePipelined(new SessionCallback<String>() {
            @Override
            public String execute(RedisOperations operations) throws DataAccessException 			{
                Person person = new Person();
                person.setId(1);
                person.setName("zhangsan");
                person.setAge(20);
                long start = System.currentTimeMillis();
                for (int i = 1; i < 10000; i++) {
                    operations.opsForValue().set("person" + i, "person:" + person);
                }
                System.out.println(System.currentTimeMillis()-start); //312ms
                return null;
            }
        });
        System.out.println(System.currentTimeMillis()-start);//2123ms
    }
}
管道存储10000个对象,用时约2123ms

image

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐