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测试后存储的数据 |
---|
打印结果 |
在第一张图中发现存储的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指定序列化器后存储的数据 |
---|
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使用结果 |
---|
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存储对象 |
---|
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 |
---|
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。