Jedis
我们要使用java 来操作redis
什么是Jedis:
Jedis是Redis官方推荐的java连接开发工具,使用java操作Redis中间件。
1、导入jar包
<!--导入jedis的jar包-->
<dependencies>
<!-- 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.70</version>
</dependency>
</dependencies>
2、测试连接
package com.kuang;
import redis.clients.jedis.Jedis;
public class TestPing {
public static void main(String[] args) {
//1.创建对象
Jedis jedis = new Jedis("127.0.0.1",6379);
System.out.println(jedis.ping());
}
}
常用API
String
List
Set
Hash
Zset
和之前学的命令一样
事务操作
package com.kuang.base;
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class TestTx {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.flushDB();
JSONObject jsonObject = new JSONObject();
//给json添加数据
jsonObject.put("age",10);
jsonObject.put("name","haohao");
//开启事务
Transaction multi=jedis.multi();
String result = jsonObject.toJSONString();//将json转为字符串
// jedis.watch(result); 开启监控检测result
try{
multi.set("user1",result);
multi.set("user2",result);
// int i=1/0; //代码抛出异常事务,执行失败
multi.exec();//执行事务
} catch (Exception e) {
multi.discard(); //放弃事务
e.printStackTrace();
}
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
}
}
SpringBoot整合
SpringBoot操作数据: spring-data jpa jdbc mongodb redis
说明:在SpringBoot2.x之后,原来使用的 jedis被替换为了lettuce?
jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用 jedis pool 连接池 !更像 BIO
lettuce :采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况! 可以减少线程数据了, 更像Nio 模式
源码分析
@Bean
@ConditionalOnMissingBean( name = {"redisTemplate"})//不存在才生效,我们可以自己写去替换
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
//Redis对象是需要序列化!
//两个泛型都是Object,Object的类型,我们需要强转<String,Object>
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
Spring Boot中jedis连接池里面都没有注入,所以不能用jedis,用lettuce
1、导入依赖
<!--操作redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置
#配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
3、测试
package com.kuang;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 操作不同的数据类型 ,api和我们的指令是一样的
//opsForValue 操作字符串 类似String
//获得redis的连接对象
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushDb();
// connection.flushAll();
redisTemplate.opsForValue().set("myset","hello");
System.out.println(redisTemplate.opsForValue().get("myset"));
}
}
关于对象的保存:
新get的知识点:
1、lombok插件以及相关注解
Lombok注解介绍
@Data:注解在类上,将类提供的所有属性都添加get、set方法,并添加、equals、canEquals、hashCode、toString方法
@Setter:注解在类上,为所有属性添加set方法、注解在属性上为该属性提供set方法
@Getter:注解在类上,为所有的属性添加get方法、注解在属性上为该属性提供get方法
@NotNull:在参数中使用时,如果调用时传了null值,就会抛出空指针异常
@Synchronized 用于方法,可以锁定指定的对象,如果不指定,则默认创建一个对象锁定
@Log作用于类,创建一个log属性
@Builder:使用builder模式创建对象
@NoArgsConstructor:创建一个无参构造函数
@AllArgsConstructor:创建一个全参构造函数
@ToStirng:创建一个toString方法
@Accessors(chain = true)使用链式设置属性,set方法返回的是this对象。
@RequiredArgsConstructor:创建对象
@UtilityClass:工具类
@ExtensionMethod:设置父类
@FieldDefaults:设置属性的使用范围,如private、public等,也可以设置属性是否被final修饰。
@Cleanup: 关闭流、连接点。
@EqualsAndHashCode:重写equals和hashcode方法。
@toString:创建toString方法。
2、ObjectMapper().writeValueAsString(user)
/* * writeValueAsString方法将一个对象转换成字符串的时候,使用了这个对象的get方法, * 如果被转换的对象没有get方法,writeValueAsString是无法正常执行的,但是不会报错*/ String jsonUser = new ObjectMapper().writeValueAsString(user);
默认的是jdk序列化,如果我们不想使用默认的,可以自己定义
编写自己的RedisTemplate
固定模板,可以直接使用
package com.kuang.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
@Configuration
public class RedisConfig {
//自己定义了一个RedisTemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//我们为了开发方便,直接使用<String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
//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;
}
}
但是要确保序列化注入之用的是我们自己写的配置
因为底层也有RedisTemplate,为了防止歧义,可以输入指定名称
自己开发工具包,不用原生的API。
学习Redis更重要的是学习Redis的每一种数据结构的用处和作用场景