Redis基础知识:
String常见命令
我们在工程中常见的方式:
我们在项目中使用String时,使用这种方式我们在redis视图工具中看见的就是层级结构
set heima:user:1 '{"name":"lihua","age":"11"}'
我们在新增数据时可以直接使用setnx:如果存在就插入,失败就是返回0
Hash常见命令
List类型的常见命令和用法:
SET类型常见命令
127.0.0.1:6379> sadd zhangsan lisi wangwu zhaoliu
(integer) 3
127.0.0.1:6379> sadd lisi wangwu mazi ergou
(integer) 3
127.0.0.1:6379> SCARD zhangsan
(integer) 3
127.0.0.1:6379> SINTER zhangsan lisi
1) "wangwu"
127.0.0.1:6379> sdiff zhangsan lisi
1) "zhaoliu"
2) "lisi"
127.0.0.1:6379> sunion zhangsan lisi
1) "ergou"
2) "lisi"
3) "wangwu"
4) "zhaoliu"
5) "mazi"
127.0.0.1:6379> sismember zhangsan lisi
(integer) 1
127.0.0.1:6379> sismember lisi zhangsan
(integer) 0
127.0.0.1:6379> srem zhangsan lisi
(integer) 1
127.0.0.1:6379> scard zhangsan'
Invalid argument(s)
127.0.0.1:6379> scard zhangsan
(integer) 2
127.0.0.1:6379> smembers zhangsan
1) "zhaoliu"
2) "wangwu"
127.0.0.1:6379>
SortedSet常见命令:
java整合redis :
redis客户端:
我们进入官网之后可以查看我们java语言的客户端,标有五角星的是建议我们使用的。
进入官网之后我们可以看见当前建议使用的客户端。
Jedis客户端:
导入依赖:
<dependencies>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
快速开始:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
public class jedisTest {
private Jedis jedis;
@BeforeEach //我们使用的是maven项目,使用的是junit5 这个注解是在所有的测试内容开始之前要执行的任务
public void setUp() {
//建立连接
jedis =new Jedis("localhost", 6379);
//选择使用的数据库
jedis.select(0);
System.out.println("建立连接完成");
}
@Test
public void test() {
//提前插入,后面一定会失败
jedis.set("name","lihua");
long setnx = jedis.setnx("name", "lihua");
if(setnx>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
}
@AfterEach
public void tearDown() {
jedis.close();
System.out.println("关闭连接");
}
}
hash类型:
/**
* 尝试使用hash类型
*/
@Test
public void testHash(){
jedis.hset("user1","name","lihua");
jedis.hset("user1","age","12");
String name = jedis.hget("user1", "name");
System.out.println("name:"+name);
//获取map数据
Map<String, String> map = jedis.hgetAll("user1");
System.out.println("map = " + map);
}
其他的类型我们不在演示,他和我们直接使用redis时的命令是一致的,只要大家记得命令就就可以了。
解决Jedis的并发问题:
创建线程池:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* 创建jedis工厂
*/
public class JedisConnectionFactory {
private static JedisPool jedisPool;
static{
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数
config.setMaxTotal(8);
//设置最大空闲
config.setMaxIdle(8);
//最小空闲
config.setMinIdle(0);
//设置连接等待时间 默认是-1 就是一致等
config.setMaxWaitMillis(1000L);
jedisPool = new JedisPool(config, "127.0.0.1", 6379);
}
public static Jedis getInstance(){
return jedisPool.getResource();
}
}
使用连接池实现:
private Jedis jedis;
@BeforeEach //我们使用的是maven项目,使用的是junit5 这个注解是在所有的测试内容开始之前要执行的任务
public void setUp() {
//建立连接
jedis = JedisConnectionFactory.getInstance();
//选择使用的数据库
jedis.select(0);
System.out.println("建立连接完成");
}
/**
* 尝试使用连接池的方式获取jedis
*/
@Test
public void testList(){
String hget = jedis.hget("user1", "name");
System.out.println(hget);
}
@AfterEach
public void tearDown() {
jedis.close();
System.out.println("关闭连接");
}
spring-boot整合redis
导入依赖:
对于我们的依赖,有的人可能在编写配置文件时,将线程池的参数直接配置的,但是没有引入我们的commons-pool的依赖,这是就会出现错误。
<!--配置redis依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--为了并发条件,需要连接池common-pool2--> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
填写配置文件:
server:
port: 8080
spring:
redis:
host: 127.0.0.1 # 小编装在了windows环境中了 如果是虚拟机的话,填自己的虚拟机地址
port: 6379 #端口号,其实可以不配置,直接是直接使用默认值
lettuce:
pool:
max-wait: -1ms
max-idle: 8
min-idle: 0
max-active: 8
# 千万注意如果使用连接时参数,必须引入我们的commons-pool依赖
注入RedisTemplate
@Autowired private RedisTemplate redisTemplate;
测试代码:
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.core.RedisTemplate;
@SpringBootTest
public class PoolTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test1() {
/**
* 如果不存在就直接插入
*/
Boolean b = redisTemplate.opsForValue().setIfAbsent("name", "李奤u");
System.out.println(b);
}
@Test
public void test2(){
System.out.println(redisTemplate.opsForValue().get("name"));
}
}
序列化和反序列化:
我们可以发现,我们直接进行存储时,我们的字符串被序列化为字节了,使用的是JDK的默认序列化方式,这样一个缺点是不便于阅读,另一个缺点是占用的空间大,所以我们可以设置我们的序列化方式,设置的方法入下:
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setKeySerializer(RedisSerializer.string());
return redisTemplate;
}
}
再次演示:
序列化成功。
StringTemplate:
我们通过配置redisTemplate的方式实现了自定义的序列化和反序列化,但是我们在储存时会记录我们这个序列化的Object的类型,浪费存储空间,所以我们使用StringRedisrtrmplate来序列化和反序列化。
下面展示做法:
注意点:我们在编写实体类时,需要写一个默认构造函数,不然容易出现无法预料的错误。
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hdk.redis_boot.entity.User;
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.core.StringRedisTemplate;
@SpringBootTest
public class TestString {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void test() throws JsonProcessingException {
/**
* 我们尝试将user对象放置到redis中
* 将user序列化为json字符串,他的序列胡和反序列化的操作交给程序猿节省空间
*/
//我们展示时使用的时ObjectMapper 这个时我们的springMvc自带的序列化的工具,大家也可以使用hutool或者是fastJson
ObjectMapper objectMapper = new ObjectMapper();
//创建对象
User user = new User(1,"王虎");
//手动序列化
String json = objectMapper.writeValueAsString(user);
System.out.println("打印json字符串"+json);
//将数据写入redis
stringRedisTemplate.opsForValue().set("user1",json);
//获取值
String value =stringRedisTemplate.opsForValue().get("user1");
//手动反序列化
User user1 = objectMapper.readValue(value, User.class);
System.out.println(user1);
}
}
RedisTemplate的Hash操作:
@Test
public void testHash(){
stringRedisTemplate.opsForHash().put("user1","name","zhangsan");
stringRedisTemplate.opsForHash().put("user1","age",11);
}