Redis基础—七、springboot整合redis
一、准备工作
我们在springboot中操作数据主要使用的是springdata,里面包含jdbc,mybatis,mongodb等等。
在springboot集合redis的过程中,我们也要使用spring-data进行一个配置的操作。
首先我们新建一个springboot项目,把相关的包导一下,redis的包在Nosql中,顺便web和一些开发工具也导进来。
然后我们点进去redis-starter的源码看一下,发现了惊天大秘密。
我们发现starter里面居然没有配置jedis,官方推荐的咋不见了,咋换成这个lettuce了。
首先我们看看这两个的本质区别:
jedis:采用的是直连,多个线程操作是不安全的,如果想要避免,使用jedis pool连接池!BIO
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
所以说为了解决高并发下的操作,springboot在2之后就是用了lettuce作为内核。
二、撸源码,康原理
首先我们看看spring帮我们做了啥,看一下
lib下找一下springFactories,里面找到redis的自动配置。
我们发现spring为我们自动配置了两个模板
在默认的情况下,如果没有配置redisTemplate以及StringRedisTemplate,这两个模板就会生效。
其中上面的那个是所有类型通用的,泛型传入两个object类,下面是string类专用的。我们点进去上面的RedisPropeties.class看看它为我们配置了哪些属性值。
private int database = 0; #选择第几个库
/**
* Connection URL. Overrides host, port, and password. User is ignored. Example:
* redis://user:password@example.com:6379
*/
private String url;
/**
* Redis server host.
*/
private String host = "localhost";
/**
* Login username of the redis server.
*/
private String username;
/**
* Login password of the redis server.
*/
private String password;
/**
* Redis server port.
*/
private int port = 6379;
/**
* Whether to enable SSL support.
*/
private boolean ssl;
/**
* Read timeout.
*/
private Duration timeout;
/**
* Connection timeout.
*/
这里截取了一部分常用的,我们发现常用的信息诸如端口号啊,用户名啥的,当然我们可以自己配
那我们去修改一下,相关的信息,主要修改一下主机名就好了!
spring.redis.host= xxxx
之后再测试类编写一手很简单的代码
redisTemplate.getConnectionFactory().getConnection().flushDb();
redisTemplate.opsForValue().set("jj","zjj");
System.out.println(redisTemplate.opsForValue().get("jj"));
大家如果redis语句学好的话这块必然是没啥问题的。
输出成功!去服务器上看看。
我们输出keys *看一下
发现这个key不大一样啊!
这个是因为其默认template的序列器与redis服务器上的不大一致,导致会有些编码无法识别,这时我们就需要重写下template。
三、自定义template以及RedisUtil
由于我们再序列化中遇到了一些不知到咋回事儿的编码,我们要自定义一个template.
这里我们创建一个RedisConf配置类,我们拿一个现成人家给咱配好的。
package com.dll.springredis.conf;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConf {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//更改默认的序列化类为Jackson2JsonRedisSerializer
Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//json序列化配置
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
objectJackson2JsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value的序列化方式采用jackson
template.setValueSerializer(objectJackson2JsonRedisSerializer);
//hash的value序列化方式采用jackson
template.setHashValueSerializer(objectJackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
我们可以看见了与value相关的序列器已经变成了Jackson2JsonRedisSerializer,我们再次测试一下原来的代码。
这里我们传进去一个对象试试。
我们定义一个User类,然后将其进行序列化。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String name;
private int age;
}
测一下。
@Test
void Test2(){
redisTemplate.opsForValue().set("myjj",new User("zjj",21));
System.out.println(redisTemplate.opsForValue().get("myjj"));
}
没啥问题。
在我们真实的企业开发中,经常会将经常使用的模块打包成一个Utils,Utils中调用原生的接口方法并进行一些操作,比如说异常的处理等等等。
这里我们也拿一个Utils。
大家跟 https://www.cnblogs.com/zhzhlong/p/11434284.html
拿就行。
大家可以根据自己需求来更改一下。