1.简介
spring-data是和spring-boot齐名的项目,在spring-data中有jpa,jdbc,redis,mongodb等数据持久化方式,对于redis,springboot2.x开始将jedis替换成了lettuce。
jedis :采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool 连接池!BIO模式
lettuce :采用netty (netty也是必学的技术栈),实例可以再多个线程中进行共享,不存在线程不安全的情况!减少线程数量,NIO模式
2.配置redis
(1)配置原理:
spring-boot所有的配置类都有一个自动配置类,XXXAutoConfiguration,这里就是RedisAutoConfiguration ,而每个配置类都对应了XXXproperties这个文件便是默认配置信息
点击这个类,进入配置类,得到配置文件redisproperties所在位置,里面就是redis的默认配置,
当然也可以自己更改为别的:
(2)模板类源码,spring-boot有大量的入门模板类,如jdbctemplate,redistemplate等
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
//@ConditionalOnXXX表示条件成立就是用这个类
//这里的意思就是如果以及自己没写redisTemplate,就是用这个默认的
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
//默认的RedisTemplate 没有过多的设置,redis对象都是需要序列化!
//两个泛型都是object,object 的类型,我们后使用需要强制转换<String, object>
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
(3)连接
1)导入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2)配置连接(前面已经说到了配置文件)
spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.database=1
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-active=8
#...还有很多...
3)测试
RedisTemplate.opsForXXX.XX():就是对某种类型的一些处理方法
也有也写基本的常用操作可以直接调用
比如,这段代码进行测试:
@SpringBootTest
class SpringbootRedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//opsForXXX.XX()
System.out.println(redisTemplate.opsForValue().get("user"));
}
}
运行结果:
在命令行中输入中文的key或value如果输入中文会出现乱码,可是使用RedisTemplate为什么就不会了呢?这个问题,是因为RedisTemplate进行了序列化:查看RedisTemplate源码
3.自定义配置类
前面说了RedisTemplate用了jdk的序列化,那如果我们需要用别的序列化,比如json的方式,我们就可以自定义一个配置类
首先讲一下序列化的东西:我们自定义一个类User,不进行序列化
@Component
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private Integer age;
}
然后进行测试:
@SpringBootTest
class SpringbootRedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() throws JsonProcessingException {
//自定义了一个User类,开发中一般是用json字符串存值的
User user1=new User("董李",19);
User user2=new User("碧瑜",20);
String usrStr=new ObjectMapper().writeValueAsString(user1);
redisTemplate.opsForValue().set("user1",usrStr);
System.out.println(redisTemplate.opsForValue().get("user1"));
redisTemplate.opsForValue().set("user2",user2);
System.out.println(redisTemplate.opsForValue().get("user2"));
}
}
结果发现,使用json字符串的成功,而直接使用对象的报错了
然后我们给User加上序列化关键字Serializable,再测试:发现成功了,这是因为json自带了序列化,所以不用加关键字也能成功.
序列化实现了,但是我们想使用别的序列化方式,不适用默认的,接下来讲讲怎么配置自己定义的RedisAutoConfiguration类
1)从RedisAutoConfiguration类中复制自己想要修改的内容,然后改成自己想要的:
/**
* 自定义redis配置类
*/
@Configuration
public class RedisConfig {
@Bean("myRedisTemplate")
@SuppressWarnings("all")
//自定义的配置,为了开发方便,一般使用<String, Object>
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//序列化的自定义配置,使用Json进行序列化
Jackson2JsonRedisSerializer jsonRedisSerializer=new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om=new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer strSerializer=new StringRedisSerializer();
//key使用String的序列化方式
template.setKeySerializer(strSerializer);
//HashKey使用String的序列化方式
template.setHashKeySerializer(strSerializer);
//Value使用Json的序列化
template.setValueSerializer(jsonRedisSerializer);
//HashValue使用Json的序列化方式
template.setHashValueSerializer(jsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
2)再次进行测试,从控制台中查看,发现没有进行转意字符的处理了
4)自定义工具类
在实际开发中,一般不会直接使用RedisTemplate提供的api,而是自定义工具类,因为常用的api就这些,多余的不需要,而且不用重复的写一些相同的代码.
@Component
public class RedisUtils {
@Autowired
@Qualifier("myRedisTemplate")
private RedisTemplate<String,Object> redisTemplate;
/**
* 写自己的工具类内容
*/
}
比如: