一、java如何操作redis——Jedis
- jedis的“j”就是java
- jedis是java官方推荐的java操作redis工具,是一个非可视化的客户端redis-client
- springboot的redisTemplate对象就相当于这里的jedis对象(redisTemplate去调用一系列方法不就相当于jedis这个client去调用一系列方法吗?remember一下ES的client),虽然以后工作中都是用springboot集成redis,也就是说以后不会再用jedis了。但是我们还是要学习一下。
1、导入依赖
需要两个依赖,一个肯定是jedis依赖。再就是需要把java对象转Json,那就需要一个JSON包,这里我们用fastjson
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
2、配置
不用配,服务器地址和端口号待会在方法里去配
3、Jedis 的API跟redis命令一模一样
测试连接成功否
public class demo {
public static void main(String[] args) {
Jedis j = new Jedis("121.36.42.22",6380);
j.auth("CsiFlow!@#680"); // 密码
System.out.println(j.ping()); //返回“PING”则成功
}
}
二、springboot集成redis
1、新建一个springboot项目
2、添加redis依赖包
可以在新建项目的时候就选上
也可以建完项目以后手动导入pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3、配置
在application.yml文件中进行如下配置:
spring:
redis:
host: 121.36.42.22
port: 6380
# 数据库索引
database: 0
password: CsiFlow!@#680
# 连接超时时间
connect-timeout: 10s
# springboot2.x之后把jedis换成了lettuce
lettuce:
pool:
min-idle: 0 # 最小空闲连接
max-idle: 8 # 最大空闲连接
max-active: 8 # 连接池的最大连接数
max-wait: -1ms # 连接池的最大阻塞等待时间(负值表示没有限制
PS: 在springboot2.x之后把原来使用的jedis换成了lettuce,因为jedis线程不安全,而lettuce的底层是netty,新能更高。并且jedis从spring-boot-starter-data-redis源码中扣除了,也就是springboot2.x以后只能用lettuce了。
4、看自动配置的源码
应该找到RedisAutoConfiguration才对
但是我们在这里找到了这个文件
找到了其配置文件所在类RedisProperties
在这里可以看到都有什么可配置项(在application.yml里),有什么已经配好默认值了。
@AutoConfiguration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class) //指明配置文件
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate") //ConditionalOnMissingBean注解,如果我们自己写了一个redisTemplate的bean就替代默认的这个
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { //默认的redisTemplate是<Object,Object>类型的,但是我们一般会自己写一个<String,Object>类型的
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean //因为String类型是redis最常用的类型,所以单独给这个类型写了一个redisTemplate
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}
5、常用操作
先@Autowired注入自动配置好的redisTemplate,然后redisTemplate可以调用一系列方法,这些方法对应我们redis里的指令。
6、上手测试
@SpringBootTest
class SpringbootMybatisApplicationTests {
@Resource
RedisTemplate redisTemplate;
@Test
public void test01(){
redisTemplate.opsForValue().set("mykey","Tuesday");
System.out.println(redisTemplate.opsForValue().get("mykey"));
}
}
测试成功
所以数据写到我们在application.yml里配置的db0里面去了吗?是这样的。但是前面有一串符号,这是redis控制台的原因,设置一下就好了
三、自定义redisTemplate实现java对象序列化
企业实际开发中,所有的pojo类都要implements Serializable实现序列化!
实体类可序列化以后,就可以直接传这个对象了。
但是我们在学 implements serializable的时候就说过,实际开发中并不使用这种JDK自带的序列化方式,之前就介绍过原因:
企业中通常采用的是JSON这种文本类序列化的方式,酱紫:
@Test
public void test01(){
// 1.从数据库中取出一条数据,转为java对象
Blog blogs = blogMapper.selectById(2);
// 2.java对象-->json
String blogString = JSON.toJSONString(blogs);
// 3. 存到redis里
redisTemplate.opsForValue().set("blog",blogString);
}
如果我们还想再简化一点,不需要每次存redis的时候都调用JSON.toJSONString,那就重写redisTemplate,直接指定序列化方式!下面给出固定模板:
/**
* redis配置
*/
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
//<String, Object>是我们最常用的类型
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,Object> template = new RedisTemplate<String,Object>();
template.setConnectionFactory(factory);
//配置:用jackson进行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;
}
}
然后我们会封装一个RedisUtils.java工具类,这样我们调用redis方法的时候会更加简单。
package com.example.demo.springbootmybatis.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component //别忘了注入这个工具类
public final class RedisUtils {
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate<String,Object> redisTemplate;
/**
* set命令
* @param key
* @param value
* @return
*/
public boolean set(String key,Object value){
try {
redisTemplate.opsForValue().set(key,value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* get命令
* @param key
* @return
*/
public Object get(String key){
return (key == null)? null : redisTemplate.opsForValue().get(key);
}
/**
* 指定key的时效时间
* @param key
* @param time
* @return
*/
public boolean expire(String key, long time){
try {
if(time > 0){
redisTemplate.expire(key,time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 还有其他命令,在RedisUtils工具类里要写30多个勒
*/
}
测试一下:
@Autowired
@Qualifier("redisUtils")
RedisUtils redisUtils;
@Test
public void test02(){
Blog blog1 = blogMapper.selectById(2);
redisUtils.set("blog1",blog1);
System.out.println(redisUtils.get("blog1"));
}
变得如此丝滑~
而且在控制台里没有乱码了