Redis
1.认识redis
1.1什么是NoSQL
NoSQL是非关系数据库
- 数据结构:非结构化
- 数据关联:非关联的
- 查询方式:非SQL查询
- 事务特性:BASE(无法满足事务的ACID)
使用场景
- 数据结构不固定的
- 对一致性,安全性要求不高
- 对性能有要求
1.2什么是Redis
Redis是一个基于内存的键值型NoSQL数据库
特征
- 键值:支持多种不同的数据结构功能丰富
- 单线程,每个命令具备原子性
- 低延迟,速度快(基于内存,IO多路复用,良好的编码)
- 支持数据持久化
- 支持主从集群,分片集群
- 支持多语言客户端
2.Redis常见命令
2.1Redis数据结构
Redis是一个key-value的数据库,key一般是String类型,value的类型多种多样
value基本类型
- String 字符串
- Hash hash表
- List 有序集合(链表)
- Set 无序集合
- SortedSet 可排序集合
2.2Redis通用命令
通用命令是指部分数据类型都可以使用的命令
- KEYS:查看所有符合模板的key(**支持模糊查询,通配符为* **)
- DEL:删除一个指定的key
- EXISTS:判断key是否存在
- EXPIRE:给一个可以设置有效起,有效期到期时该key自动删除
- TTL:查看一个key的剩余有效期
2.3String类型
String是字符串类型,是Redis最简单的一种存储类型,其value是字符串
根据字符串格式分为三类:
- String:普通字符串
- int:整数类型,可以做自增或自减操作
- float:浮点类型,可以做自增或自减操作
无论是哪种类型,底层都是字节数组形式储存,只是编码方式不同,最大空间不能超过512m
2.3.1String类型常用命令
常见命令
- SET:添加或修改一个String类型的键值对
- GET:根据key获取String类型的value
- MSET:批量添加键值对
- MGET:根据多个key获取多个String类型的value
- INCR:让一个整形的key自增11
- INCRBY:让一个整形的key自增并指定长度
- INCRBYFLOAT:让一个浮点类型数字自增并指定长度
- SETNX:添加一个String类型的键值对,前提是key不存在,否则不执行
- SETEX:添加一个String类型的键值对,指定有效期
思考
Redis作为一个非关系型数据库是没有Table的,如何区分不同类型的key?
可以使用key的分级存储用:
例如:
2.4Hash类型
hash类型,也叫散列,value是一个无序字典
String结构是将对象序列化成josn字符串后存储,当需要修改某个对象字段时很不方便
Hash结构可以将对象中每个字段独立存储,可以对单个字段做CRUD
2.4.1Hash类型常用命令
常用命令
2.5List类型
Redis中的List类型与java中的LinkedList类似,可以看作一个双向链表的结构,支持正向检索,也支持反向检索
2.5.1List常用命令
常用命令
思考
2.6Set类型
Redis中的Set结构与java中的HashSet类似,可以看作是一个没有value的HashMap
2.6.1Set常用命令
常用命令
2.7SortedSet类型
Redis是一个可排序的Set集合,底层结构中Sorted每一个元素都有一个score属性,基于score属性对元素进行排序,底层实现是一个跳表(SkipList)加Hash表.跳表用作排序
2.7.1SortedSet常见命令
常见命令
3.Redis的Java客户端
3.1Jedis客户端
3.1.1Jedis快速入门
快速入门
- 1.引入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
- 2.建立连接
@BeforeEach
void setUp(){
//建立连接
jedis= new Jedis("192.168.41.128",6379);
//设置密码\
jedis.auth("123321");
//选择库
jedis.select(0);
}
- 3.测试
@Test
void testString(){
//存入数据
String result=jedis.set("name","虎哥");
System.out.println("result = " + result);
//获取数据
String name = jedis.get("name");
System.out.println("name = " + name);
}
@Test
void testHash(){
//存入hash数据
jedis.hset("user:1","name","Jack");
jedis.hset("user:1","age","20");
//获取hash数据
Map<String, String> usr1 = jedis.hgetAll("user:1");
System.out.println("usr1 = " + usr1);
}
- 4.释放资源
@AfterEach
void tearDown(){
if (jedis!=null){
jedis.close();
}
}
注意:需要开启redis服务端,关闭防火墙
3.1.2Jedis连接池
Jedis本身线程是不安全的,并且频繁的创建何销毁连接会有性能损耗,因此推荐使用jedis连接池来代替jedis直连方式.
创建jedis连接池
public class JedisConnectionFactory {
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.41.128",6379,1000,"123321");
}
//返回jedis对象
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
@BeforeEach
void setUp(){
//建立连接
// jedis= new Jedis("192.168.41.128",6379);
//连接池中获取jedis
jedis= JedisConnectionFactory.getJedis();
//设置密码\
jedis.auth("123321");
//选择库
jedis.select(0);
}
需要注意的是使用连接池中的jedis释放资源时不会直接释放掉,而是将其放回连接池中
3.2SpringDateRedis
SpringDate是Spring中数据操作的模块,包含对各种数据库的集成.其中对Redis数据库的集成模块就叫做SpringDateRedis
3.2.1SpringDateRedis快速入门
SpringDateRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作,并且将不同数据类型的操作API封装到不同的类型中:
快速入门
- 1.引入依赖
<!-- Redis依赖 -->
<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: 192.168.41.128
port: 6379
password: 123321
lettuce:
pool:
max-active: 8 #最大连接
max-idle: 8 #最大空闲
min-idle: 0 #最小空闲
max-wait: 100 #连接最大空闲时间
- 3.注入RedisTemplate
@Autowired(required = false)
private RedisTemplate redisTemplate;
- 4.编写测试
@Test
void testString(){
redisTemplate.opsForValue().set("name","子路");
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
}
3.2.2SpringDateRedis的序列化方式
RedisTemplate可以接收任意Objet最为值写入Redis,但是jdk默认的序列化方式是将Object
按字符数组形式写.
缺点:
- 可读性差
- 占用内存
所以需要自定义RedisTemplate序列化方式
编写一个配置类,自定义Redis序列化方式
@Bean
public RedisTemplate<String,Object> redisTemplate( RedisConnectionFactory connectionFactory){
//创建RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
//设置连接工厂
template.setConnectionFactory(connectionFactory);
//创建josn序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//设置key的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
//设置value的序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
template.afterPropertiesSet();
//返回
return template;
}
创建User对象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String name;
private Integer age;
}
更改注入依赖的泛型
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Test
void testString(){
redisTemplate.opsForValue().set("name","子路");
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
}
@Test
void User(){
redisTemplate.opsForValue().set("user",new User("zlsame ",24));
User zlsame = (User) redisTemplate.opsForValue().get("user");
System.out.println("zlsame = " + zlsame);
}
3.2.3使用StringRedisTemplate手动序列化
思考
所以为了节省内存空间,我们并不会使用自动序列化和反序列化,当我们要存储对象时,会手动完成序列化和反序列化
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final ObjectMapper mapper =new ObjectMapper();
@Test
void testString() {
stringRedisTemplate.opsForValue().set("name", "子路");
Object name = stringRedisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
}
@Test
void User() throws JsonProcessingException {
//创建对象
User user = new User("zlsame ", 24);
//手动序列化
String josn = mapper.writeValueAsString(user);
//写入数据
stringRedisTemplate.opsForValue().set("user:001",josn);
//获取数据
String o = stringRedisTemplate.opsForValue().get("user:001");
//手动反序列化
User user1 = mapper.readValue(o,User.class);
System.out.println("user1 = " + user1);
}
标签:name,Redis,jedis,key,序列化,String
From: https://www.cnblogs.com/zlsame/p/17432686.html