1. Jedis 的基本使用
什么是 Jedis? github 上面是这样描述的:
- Jedis is a blazingly small and sane Redis java client.
- Jedis was conceived to be EASY to use.
- Jedis is fully compatible with redis 2.8.x, 3.x.x and above*.
大致意思:Jedis 是 Redis 官方推荐的 Java 连接开发工具!使用 Java 来操作 Redis 中间件。类似于 JDBC 吧。
如果想要使用 Java 来操作 Redis,那么就一定要对 Jedis 十分地熟悉(即:对 Redis 五大基本数据类型的操作命令熟悉)
例如:String 类型的命令
set key value # 给 key 设置 value
get key # 获取 key 对应的 value
append key value # 如果 key 存在,则追加;否则,相当于 set 命令
setnx key value # 如果 key 不存在,就设置
getset key value # 先 get,再 set
...
实战
1、创建一个 Maven 项目,并导入 Pom 依赖
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
2、编码测试
- 连接 redis
- 操作命令
- 断开连接
public class TestPing {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
System.out.println(jedis.ping());
}
}
Jedis 对象中的方法就是 Redis 中数据类型的操作命令
如果程序返回 PONG,表示使用 Java 连接 Redis 成功!
接下来,简单地操作下 String 类型:
public class TestPing {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
System.out.println("清空数据:" + jedis.flushDB());
System.out.println("判断某个键是否存在:" + jedis.exists("username"));
System.out.println("添加一个键值对:" + jedis.set("username", "zzc"));
System.out.println("系统中所有的键如下:");
System.out.println(jedis.keys("*"));
}
}
结果如下:
重点是要对 Redis 的操作命令熟悉,这样使用 Jedis 时才能得心应手!!
2 Jedis 中使用事务
public class TestTx {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
JSONObject json = new JSONObject();
json.put("name", "zzc");
json.put("age", 18);
jedis.flushDB();
// 1. 开启事务
Transaction ts = jedis.multi();
try {
ts.set("user", json.toString());
// 2. 执行事务
ts.exec();
} catch (Exception e) {
// 回滚事务
ts.discard();
} finally {
System.out.println(jedis.get("user"));
jedis.close();
}
}
}
3. 使用 SpringBoot 整合 Redis
创建一个 SpringBoot 项目,并引入依赖 Redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
点进去 spring-boot-starter-data-redis,查看其 POM 文件:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.4.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.0.2.RELEASE</version>
<scope>compile</scope>
</dependency>
这个里面只有 lettuce,而没有 jedis。
【注意】:SpringBoot 2.x 之后,原来使用的 jedis 被替换为了 lettuce
jedis 与 lettuce 之间区别?
- jedis:采用直连的方式,多线程是不安全的;要想避免多线程安全,则需要使用 jedis pool 连接池!类似于 BIO
- lettuce:采用 Netty 的方式,实例可以在多个线程中共享,多线程安全。类似于 NIO
在 Springboot 配置原理中,涉及到以下两方面:
- SpringBoot 中所有的配置类,都有一个自动配置类。RedisAutoConfiguration
- 自动配置类都会绑定一个配置文件 properties。RedisProperties
源码分析:
@Bean
// 这个注解@ConditionalOnMissingBean表示:如果name为“redisTemplate”的bean存在,这该注解修饰的代码块不执行。
@ConditionalOnMissingBean(name = {"redisTemplate"})
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化的(类似于 Dubbo)
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;
}
使用 SpringBoot 操作 Redis:
- 导入依赖
- 配置连接:可以使用默认配置
- 编码测试
单元测试:
@SpringBootTest
class SbApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test () {
redisTemplate.opsForValue().set("name", "zzc");
System.out.println(redisTemplate.opsForValue().get("name"));
}
}
但是,在命令行中查看时,key 会出现乱码(如果存储的是中文也会出现乱码)
这是因为序列化导致的。
查看 RedisTemplate.class 源码:
RedisTemplate 中有好多 序列化器
其中,默认的序列化是 JDK 序列化(它会让字符串转义)
这里我们使用 json 来序列化,就需要我们自定义一个配置类
4. 自定义 RedisTemplate
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// json 序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
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;
}
}
再次执行测试代码:
key 没有乱码了。