在SpringBoot2.x之后,原来使用的Jedis被替换成了lettuce。
Jedis:底层采用直连的方式,多个线程操作的话是不安全的,使用Jedis pool连接池!更像BIO模式。
lettuce:底层采用netty(高性能的网络框架),实例可以在多线程中共享,不存在线程不安全的情况,可以减少线程数量了(不需要开连接池了),更像NIO模式。
BIO模型:也叫阻塞式IO模型,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。
NIO模型:是非阻塞的,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮循到有IO请求时才启动一个线程进行处理。
SpringBoot所有的配置类,都有一个自动配置类 RedisAutoConfiguration
自动配置类都会绑定一个properties配置文件 RedisProperties
ctrl+f
spring.redis.host=127.0.0.1
spring.redis.port=6379
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
/**
* redisTemplate : 操作不同的数据类型
* opsForValue() : 操作字符串,类似于String
* opsForList() : 操作字List,类似于List
* opsForSet()
* opsForHash(),opsForGeo(),opsForZSet(),opsForHyperLogLog()
*/
// redisTemplate.opsForValue().set("user","111");
/**
* 除了基本的操作,常用的方法都可以通过redisTemplate进行操作,比如事务和基本的CRUD
*/
// redisTemplate.exec();
// redisTemplate.discard();
// redisTemplate.delete("user");
/**
* 获取redis的连接对象操作数据库
*/
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushDb();
// connection.flushAll();
redisTemplate.opsForValue().set("username","name");
System.out.println(redisTemplate.opsForValue().get("username"));
}
}
但是在命令行中查看:乱码。所以需要序列化!!!
源码分析:
所以需要自己定义一个配置类。
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
解决方法:把spring boot的依赖降到2.7.0以下
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")//抑制所有编译器警告
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//json的序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
1.创建对象
@Component
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String username;
private int age;
}
序列化的结果:
直接存入对象的结果:
所以所有的对象需要序列化!!!
但是命令行方式还是乱码:
2.再编写RedisTemplate(模板如上2.1)
3.运行
查看命令行:
在实际工作中,不会用原生的方法去编写代码,公司会自己封装一个RedisUtils
原生方式:
redis工具类(RedisUtil):
应用:
@Autowired
public RedisUtils redisUtils;
@Test
void test1() {
redisTemplate.set("name","bit");
System.out.println(redisTemplate.get("name"));
}