七、Jedis
我们要使用Java来操作Redis
Jedis是Redis官方推荐的java连接开发工具!使用java操作Redis中间件!如果要使用Java操作redis,那么一定要对jedis十分的熟悉!
测试
1、导入对应的依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
2、编码测试
- 连接数据库
- 操作命令
- 断开连接
public static void main(String[] args) {
//1、new Jedis 对象
Jedis jedis = new Jedis("192.168.176.100",6379);
//jedis 所有命令就是我们之前学习的命令
String ping = jedis.ping();
System.out.println(ping);
}
输出:
八、SpringBoot集成Redis
整合SpringBoot
说明:在SpringBoot2.x之后,原来使用的jedis被替换成了lettcute
jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,采用jedis pool 连接池! 更像BIO模式
lettcute:采用netty,实例可以采用多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
源码分析
@Bean
//没有 redisTemplate 这个类就默认生效这个配置类
@ConditionalOnMissingBean( name = {"redisTemplate"}) //我们可以自己定义一个redisTemplate来替换这个默认的类
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//默认的RedisTemplate没有过多的设置,对象都是需要序列化!
//两个泛型都是 Object,Object的类型都需要类型强制转换
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean //由于String 是redis中最常用的一个类型,所以单独的使用这个类
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置连接
spring.redis.host=192.168.176.100
spring.redis.port=6379
3.测试!
测试
package com.yang;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Resource
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 操作不同的数据类型
//opForValue String
//opForList List
//除了基本的操作,我们常用的方法都可以通过redisTemplate操作,和事务以及基本的CRUD
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushDb();
redisTemplate.opsForValue().set("mykey","狂神说");
System.out.println(redisTemplate.opsForValue().get("mykey"));
}
}
RedisTemplate 类
序列化配置
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
默认的序列化方式是JDK序列化,我们可能会使用Json来序列化
static RedisSerializer<Object> java(@Nullable ClassLoader classLoader) {
return new JdkSerializationRedisSerializer(classLoader);
}
对象传输需要序列化
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.pojo.User] at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96)
自定义RedisTemplate
package com.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.databind.ser.std.StringSerializer;
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;
import java.net.UnknownHostException;
/**
* @author hang yang
* @create 2023-03-22 20:32
* @description
*/
@Configuration
public class RedisConfig {
// 固定模板
//编写我们自己的RedisTemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException{
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//json序列化配置
Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//json转译
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
template.setKeySerializer(objectJackson2JsonRedisSerializer);
objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 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;
}
}
所有的redis操作,其实对于java开发人员来说,十分简单,更重要的是去理解redis的思想和每一种数据结构的用处和作用场景!