初始Redis
认识NoSQL
NoSQL:非关系型数据库
-
非结构化
-
无关联的
-
非SQL
-
BASE(事务无法完全满足ACID)
认识Redis
Redis-------远程词典服务器
特性:
-
键值型,value支持多种不同数据结构
-
单线程,每个命令具备原子性
-
低延迟,速度快(基于内存、IO多路复用、良好的编码)
-
支持数据持久化
-
支持主从集群、分片集群
-
支持多语言客户端
Redis常见命令
Redis数据结构介绍
key-value,key一般为String类型,不过value的类型多种多样
Redis通用命令
KEYS:所以符合模板的key,不建议在生产环境设备上使用 del:删除一个指定的key exists:查找指定的key是否存在 expire:为一个key设置有效期,到期自动删除 ttl:查看一个key的有效期
String类型
redis中最简单的存储模型
分为三类:
-
string:普通字符串
-
int:整数类型,可以做自增、自减
-
flost:浮点类型,可以做自增、自减
三类均为字节数组形式存储,不过是编码方式不同,字符串类型最大空间不能超过512m
redis的key允许有多个单词形成层级结构,多个单词之间用“:”隔开,格式如下:
项目名:业务名:类型:id
Hash类型
类似hashmap结构
List类型
可以看做一个双向链表结构,即支持正向检索也可以支持反向检索。
特征:
-
有序(和插入速度有关)
-
元素可以重复
-
插入和删除快
-
查询速度一般
Set类型
特征:
-
无序
-
元素不可重复
-
查找快
-
支持交集、并集、差集等功能
SortedSet类型
可排序的set集合,每一个元素都带有score属性,可以基于score属性对元素排序,底层的实现是一个跳表加hash表
特性:
-
可排序
-
元素不重复
-
查询速度快
Redis的Java客户端
jedis客户端
快速入门
1.引入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.建立连接
private Jedis jedis;
@BeforeEach
void setUp(){
//建立连接
jedis = new Jedis("127.0.0.1",6379);
}
3.测试
@Test
void test(){
String result = jedis.set("name","张三");
System.out.println(result);
String name = jedis.get("name");
System.out.println(name);
}
4.释放资源
@AfterEach
void tearDown()
{
//释放资源
if(jedis!=null)
jedis.close();
}
jedis连接池
private static final JedisPool jedisPool;
static {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//最大链接
jedisPoolConfig.setMaxTotal(8);
//最大空闲连接
jedisPoolConfig.setMaxTotal(8);
//最小空闲连接
jedisPoolConfig.setMinIdle(0);
//设置最长等待时间:ms
jedisPoolConfig.setMaxWaitMillis(200);
jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1",6379,1000);
}
//获取Jedis对象
public static Jedis getJedis(){
return jedisPool.getResource();
}
SpringDataRedis客户端
SpringData是基于Spring中数据操作的板块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis
-
提供了对不同Redis客户端的整合(Lettuce和jedis)
-
提供了RedistributionTemplate统一API来操作Redis
-
支持Redis的发布订阅模型
-
支持Redis哨兵的Redis集群
-
支持基于Lettuce的响应式编程
-
支持基于JDK。JSON、字符串、Spring对象的数据序列化及反序列化
-
支持基于Redis的JDKCollection实现
快速入门
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2.配置文件
spring:
redis:
host: 127.0.0.1
port: 6379
lettuce:
pool:
max-active: 8
max-idle: 8
min-idel: 0
max-wait: 100
3.注入RedisTemplate
@Autowired
private RedisTemplate redisTemplate;
4.编写测试
@Test
void test(){
redisTemplate.opsForValue().set("name","李四");
Object name = redisTemplate.opsForValue().get("name");
System.out.println(name);
}
SpringDataRedis的序列化方式
RedisTemplate会把Object序列化为字节形式,默认是采取JDK序列化
缺点:
-
可读性差
-
内存占用大
自定义RedisTemplate的序列化方式
@Configuration
public class demo {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
//创建Template
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
//设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//key和hashkey采用string序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
//value和hashValue采用JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
}
SpringredisTemplate
为了在反序列化时知道对象的类型,json序列化会将类的class类型写入json结果,存入Redis,会带来额外的内存开销。
为了节省内存,我们会统一使用string序列化器,要求只能存储String,所以需要手动完成对象的序列化和反序列化。
@Autowired
private StringRedisTemplate stringRedisTemplate;
//JSON工具
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testString() throws JsonProcessingException{
//准备对象
User user = new User("王五",18);
//手动序列化
String json = mapper.writeValueAsString(user);
//写入数据
stringRedisTemplate.opsForValue().set("user:200",json);
//读取
String val = stringRedisTemplate.opsForValue().get("user:200");
//反序列化
User u = mapper.readValue(val,User.class);
System.out.println(u);
}