Redis笔记(二)
基础篇
这篇笔记主要讲述在idea中开发时,如何在Java代码中使用Redis。
Redis的Java客户端
在Redis中提供了多种语言的客户端,其中Java语言推荐的客户端主要有以下三种:
-
Jedis和Lettuce:这两个主要是提供了Redis命令对应的API,方便我们操作Redis,而SpringDataRedis又对这两种做了抽象和封装,因此我们后期会直接以SpringDataRedis来学习。
-
Redisson:是在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map.Queue等,而且支持跨进程的同步机制:Lock.Semaphore等待,比较适合用来实现特殊的功能需求。
下面通过案例来演示Jedis的使用方法
Jedis入门案例
1. 创建maven工程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dm1Lvr59-1675603683590)(C:\Users\ZhouEnPei\Desktop\博客草稿\黑马点评_Redis笔记\img2\1.png)]
2. 在Pom.xml中导入依赖
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
3. 与Redis建立连接
我们在测试类中来编写与redis连接的相关代码
public class jedisTest {
private Jedis jedis;
/**
* 建立redis链接
*/
@BeforeEach
void setUp(){
jedis = new Jedis("192.168.170.139",6379);
jedis.auth("123321");
this.jedis.select(0);
}
@Test
void test(){
//存入数据
String set = jedis.set("namej", "zhaoliu");
System.out.println("result"+set);
//获取数据
String namej = jedis.get("namej");
System.out.println("取的数据是"+namej);
}
@Test
void H_test(){
//存入数据
Long hset = jedis.hset("user:1", "name", "张三");
System.out.println("result = "+hset);
//获取数据
String name = jedis.hget("user:1", "name");
System.out.println("取的数据是 :"+name);
}
@After
void close(){
if(jedis != null){
jedis.close();
}
}
}
从上面代码可以看到,使用注@BeforEach
来设定初始方法,在初始方法中创建jedis对象并设置连接redis的IP地址与端口号。使用auth()方法输入密码。使用select()方法来选定使用的数据库。
在测试方法中可以看到,在Java中操作redis的方法和在命令行中操作redis是一样的。
Jedis连接池
Jedis连接本身是不安全的,并且频繁地创建销毁连接会对性能有所损耗。影刺可以使用jedis连接池的方法来代替jedis的直连方式。可以通过工厂设计模式来创建jedis连接池
创建Jedis连接池
public class JedisConnectionFacotry {
private static final JedisPool jedisPool;
static {
//配置连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(8); //最大连接数
poolConfig.setMaxIdle(8); //最大空闲数
poolConfig.setMinIdle(0); //最小空闲数
poolConfig.setMaxWaitMillis(1000);//等待连接时间
//创建连接池对象
jedisPool = new JedisPool(poolConfig,
"192.168.170.139",6379,1000,"123321");
}
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
从上面的代码可以看到,主要就是JedisPool在起作用,这样一来,我们在需要获得连接时,只需要调用工厂类中的getJedis()方法即可。将上面的测试方法改为如下:
public class jedisTest {
private Jedis jedis;
/**
* 建立redis链接
*/
@BeforeEach
void setUp(){
// jedis = new Jedis("192.168.170.139",6379);
// jedis.auth("123321");
jedis = JedisConnectionFacotry.getJedis();
this.jedis.select(0);
}
@Test
void test(){
//存入数据
String set = jedis.set("namej", "zhaoliu");
System.out.println("result"+set);
//获取数据
String namej = jedis.get("namej");
System.out.println("取的数据是"+namej);
}
@Test
void H_test(){
//存入数据
Long hset = jedis.hset("user:1", "name", "唐三");
System.out.println("result = "+hset);
//获取数据
String name = jedis.hget("user:1", "name");
System.out.println("取的数据是 :"+name);
}
@After
void close(){
if(jedis != null){
jedis.close();
}
}
}
通过这两个案例,可以知道怎样使用jedis在Java中使用。但还需要编写许多配置代码,针对这个问题,spring做了很好的处理,让开发人员在使用jedis时更加便捷。
Redis的Java客户端-SpringDataRedis
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis
- 提供了对不同Redis客户端的整合(Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK.JSON.字符串.Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:
API | 返回值类型 | 说明 |
---|---|---|
redisTemplate.opsForValue() | ValueOperations | 操作String类型数据 |
redisTemplate.opsForHash() | HashOperations | 操作Hash类型数据 |
redisTemplate.opsForList() | ListOperations | 操作List类型数据 |
redisTemplate.opsForSet(); | SetOperations | 操作Set类型数据 |
redisTemplate.opsForStream() | StreamOperations | 操作SortedSet类型数据 |
redisTemplate | 通用命令 |
SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单
快速入门
-
在pom.xml文件中导入依赖坐标
<!--redis依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!--Jackson依赖--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
-
在yml文件中写好redis相关配置
spring: redis: host: 192.168.170.139 port: 6379 password: 123321 lettuce: pool: max-active: 8 #最大连接数 max-idle: 8 #最大空闲连接 min-idle: 0 #最小空闲连接 max-wait: 100ms #连接等待时间
-
测试代码
@SpringBootTest class SpringBootRedisApplicationTests { @Autowired private StringRedisTemplate stringRedisTemplate; void contextLoads() { redisTemplate.opsForValue().set("name","虎哥"); Object name = redisTemplate.opsForValue().get("name"); System.out.println(name); } }
在控制太可以看到打印的值是否正确。以上代码是使用演示redis中的String类型的操作方法。,其他类型同理。SpringDataRedis使用起来非常简单,记住如下几个步骤即可
SpringDataRedis的使用步骤:
- 引入spring-boot-starter-data-redis依赖
- 在application.yml配置Redis信息
- 注入StringRedisTemplate
对象序列化存入redis中String类型
在String类型存储对象数据时,一般要将对象转为json格式存到数据库中,例如现在有一个User类的对象要存入redsi中的String数据类型,我们需要先将这个User类手动转为json格式的字符串,在存储到redis中。代码演示:
-
创建一个User类
@Data public class User{ private String name; private Integer age; }
-
在测试类中测试
@SpringBootTest class SpringBootRedisApplicationTests { @Autowired private StringRedisTemplate stringRedisTemplate; //序列化类 private static final ObjectMapper mapper = new ObjectMapper(); @Test void contextLoads2() throws JsonProcessingException { User user = new user(); user.setAge(18); user.setName("张三"); //将user对象序列化 String s = mapper.writeValueAsString(user); //存到redis中 stringRedisTemplate.opsForValue().set("user:1",s); //获取value String user = stringRedisTemplate.opsForValue().get("user:1"); //将字符串反序列化为user对象 user user1 = mapper.readValue(user, user.class); System.out.println(user1); } }
上面代码中使用ObjectMapper类来进行对象的序列化和反序列化,也可以自行使用其他工具类。这样一来,存到redis数据库中的数据格式如下所示:
{ "name": "唐三", "age": 18 }
使用其他数据类型存储对象可以直接存储
@Test void testHash() { stringRedisTemplate.opsForHash().put("user:2", "name", "虎哥"); stringRedisTemplate.opsForHash().put("user:2", "age", "21"); Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:2"); System.out.println("entries = " + entries); }
控制台打印:
entries = {name=虎哥, age=21}