Redis客户端
目录
Jedis #
我们要用Java来操作Redis
什么是Jedis 是 Redis官方推荐的java连接开发工具!使用java操作redis中间件!如果要使用java操作redis,那么一定要对jedis十分的熟悉
引入依赖 #
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
编码测试 #
- 连接数据库
public class TestPing {
public static void main(String[] args) {
// new Jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379);
// jedis所有的命令就是之前学习的所有指令,所以之间的指令很重要
System.out.println(jedis.ping());
}
}
- 操作命令:所有的API对应Redis的指令,一个都没有变化。
- 断开连接
public class TestPing {
public static void main(String[] args) {
// new Jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379);
// jedis所有的命令就是之前学习的所有指令,所以之间的指令很重要
System.out.println(jedis.ping());
jedis.close();
}
}
使用事务 #
public class TestTX {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
JSONObject jsonObject = new JSONObject();
jsonObject.put("hello", "world");
jsonObject.put("name", "杨剑");
jedis.flushDB();
//开启事务
Transaction multi = jedis.multi();
String s = jsonObject.toJSONString();
try {
multi.set("user1", s);
multi.set("user2", s);
int i = 1/0; //代码抛出异常,事务执行失败
multi.exec();//执行事务
} catch (Exception e) {
multi.discard(); //放弃事务
e.printStackTrace();
} finally {
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
jedis.close();
}
}
}
SpringBoot整合 #
Springboot所有与操作数据有关的都封装到了spring-data
: jpa jdbc mongodb redis
SpringData也是和SpringBoot齐名的项目。
说明:在springboot2.x之后,原来使用的jedis被替换成了lettuce
jedis
:采用的是直连,多个线程操作是不安全的,如果想要避免,使用jedis pool连接池!BIO
lettuce
:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式。之后配置文件里面配连接池时也是使用lettuce的配置。
使用测试 #
<dependency>
<groupId>org.springframework.boot</groupId>65
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
# springboot所有的配置类,都有一个自动配置类 RedisAutoConfiguration
# 自动配置类都会绑定一个properties配置文件 RedisProperties
# 配置redis
spring.redis.host=localhost
spring.redis.port=6379
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 操作不同的数据类型,api和我们的指令是一样的
// 操作字符串,类似String类型
// redisTemplate.opsForValue();
// // 操作List
// redisTemplate.opsForList();
// //opsforset
// redisTemplate.opsForSet();
// //opsforhash
// redisTemplate.opsForHash();
// //地图
// redisTemplate.opsForGeo();
// //Zset
// redisTemplate.opsForZSet();
// //基数:hyperloglog
// redisTemplate.opsForHyperLogLog();
//除了基本的操作,常用的方法都可以直接使用,事务和基本的crud
//获取redis连接对象
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//connnection.flushDb();
//connnection.flushAll();
redisTemplate.opsForValue().set("name","yangjian");
System.out.println(redisTemplate.opsForValue().get("name"));
}
}
源码分析 #
默认的RedisTemplate没有序列化器(使用默认的JDK序列化器)需要自己配置。
通过分析源码可以发现,我们可以自己定义一个RedisTemplate来替换掉默认的。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate") //我们可以自己定义一个RedisTemplate来替换默认的
// 默认的template没有过多的设置,redis对象都是需要序列化的
//两个泛型都是object类型,我们后面使用需要强制转换<String,Object>
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean //由于String类型是Redis中最常使用的类型,所以单独提出来了一个bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
自定义RedisTemplate #
当我们希望往Redis中存入和取出对象(对象需要先实现序列化接口)时,就需要用到序列化器帮我们自动序列化和反序列化对象。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
import java.net.UnknownHostException;
@Configuration
public class RedisConfig {
//编写自己的RedisTemplate
//自己定义了一个RedisTemplate
//这是一个固定模板,拿去可以直接使用
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
//为了我们自己开发方便,一般直接使用<String,Object>
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(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;
}
}