Redis 是一种非关系型数据库(NoSQL),NoSQL 是以 key-value 的形式存储的,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求,比如说 SQL 标准,ACID 属性,表结构等等,这类数据库主要有以下特点:非关系型的、分布式的、开源的、水平可扩展的。NoSQL 使用场景有:对数据高并发读写、对海量数据的高效率存储和访问、对数据的高可扩展性和高可用性等等。
Redis 的 key 可以是字符串、哈希、链表、集合和有序集合。
Redis 的value 类型很多,包括 String、list、set、zset。
这些数据类型都支持 push/pop、add/remove、取交集和并集以及更多更丰富的操作,Redis 也支持各种不同方式的排序。为了保证效率,数据都是在缓存在内存中,它也可以周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件中。 有了 redis 有哪些好处呢?举个比较简单的例子,看下图:
Redis 集群和 Mysql 是同步的,首先会从 redis 中获取数据,如果 redis 挂了,再从 mysql 中获取数
据,这样网站就不会挂掉。更多关于 redis 的介绍以及使用场景,可以谷歌和百度,在这就不赘述了。
只要能 ping 的通云主机或者虚拟机的 ip,然后在虚拟机或者云主机中放行对应的端口(或者关掉防火墙)即可访问 redis。下面来介绍一下 redis 的安装过程:
其实还有更简单的Redis安装教程(偷个小懒O(∩_∩)O)
Spring Boot 集成 redis 很方便,只需要导入一个 redis 的 starter 依赖即可。如下:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.35version>
dependency>
这里也导入阿里巴巴的 fastjson 是为了在后面我们要存一个实体,为了方便把实体转换成 json 字符串存进去。
导入了依赖之后,我们在 application.yml 文件里配置 redis:
server:
port: 8080
spring:
#redis相关配置
redis:
database: 5
# 配置redis的主机地址,需要修改成自己的
host: 192.168.48.190
port: 6379
password: 123456
timeout: 5000
jedis:
pool:
# 连接池中的最大空闲连接,默认值也是8。
max-idle: 500
# 连接池中的最小空闲连接,默认值也是0。
min-idle: 50
# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
max-active: 1000
# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
max-wait: 2000
Spring Boot 对 redis 的支持已经非常完善了,丰富的 api 已经足够我们日常的开发,这里我介绍几个
最常用的供大家学习,其他 api 希望大家自己多学习,多研究。用到会去查即可。
有两个 redis 模板:RedisTemplate 和 StringRedisTemplate。
我们不使用 RedisTemplate,RedisTemplate 提供给我们操作对象,操作对象的时候,我们通常是以 json 格式存储,但在存储的时候,会使用 Redis 默认的内部序列化器;导致我们存进里面的是乱码之类的东西。当然了,我们可以自己定义序列化,但是比较麻烦,所以使用 StringRedisTemplate 模板。StringRedisTemplate 主要给我们提供字符串操作,我们可以将实体类等转成 json 字符串即可,在取出来后,也可以转成相应的对象,这就是上面我导入了阿里 fastjson 的原因。
新建一个 RedisService,注入 StringRedisTemplate,使用 stringRedisTemplate.opsForValue()
可以获取 ValueOperations
对象,通过该对象即可读写 redis 数据库了。如下:
public class RedisService {
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* set redis: string类型
* @param key key
* @param value value
*/
public void setString(String key, String value){
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
valueOperations.set(key, value);
}
/**
* get redis: string类型
* @param key key
* @return
*/
public String getString(String key){
return stringRedisTemplate.opsForValue().get(key);
}
}
该对象操作的是 string,我们也可以存实体类,只需要将实体类转换成 json 字符串即可。下面来测试一下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class Course14ApplicationTests {
private static final Logger logger = LoggerFactory.getLogger(Course14ApplicationTests.class);
@Resource
private RedisService redisService;
@Test
public void contextLoads() {
//测试redis的string类型
redisService.setString("weichat","GSCY");
logger.info("我的昵称为:{}", redisService.getString("weichat"));
// 如果是个实体,我们可以使用json工具转成json字符串,
User user = new User("CSDN", "123456");
redisService.setString("userInfo", JSON.toJSONString(user));
logger.info("用户信息:{}", redisService.getString("userInfo"));
}
}
先启动 redis,然后运行这个测试用例,观察控制台打印的日志如下:
我的昵称为:GSCY
用户信息:{"password":"123456","username":"CSDN"}
hash 类型其实原理和 string 一样的,但是有两个 key,使用 stringRedisTemplate.opsForHash()
可以获取 HashOperations
对象。比如我们要存储订单信息,所有订单信息都放在 order 下,针对不同用户的订单实体,可以通过用户的 id 来区分,这就相当于两个 key了。
@Service
public class RedisService {
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* set redis: hash类型
* @param key key
* @param filedKey filedkey
* @param value value
*/
public void setHash(String key, String filedKey, String value){
HashOperations<String, Object, Object> hashOperations =stringRedisTemplate.opsForHash();
hashOperations.put(key,filedKey, value);
}
/**
* get redis: hash类型
* @param key key
* @param filedkey filedkey
* @return
*/
public String getHash(String key, String filedkey){
return (String) stringRedisTemplate.opsForHash().get(key, filedkey);
}
}
可以看出,hash 和 string 没啥两样,只不过多了个参数,Spring Boot 中操作 redis 非常简单方便。来测试一下:
@SpringBootTest
public class Course14ApplicationTests {
private static final Logger logger = LoggerFactory.getLogger(Course14ApplicationTests.class);
@Resource
private RedisService redisService;
@Test
public void contextLoads() {
//测试redis的hash类型
redisService.setHash("user", "name", JSON.toJSONString(user));
logger.info("用户姓名:{}", redisService.getHash("user","name"));
}
}
使用 stringRedisTemplate.opsForList() 可以获取 ListOperations
listOperations
redis 列表对象,该列表是个简单的字符串列表,可以支持从左侧添加,也可以支持从右侧添加,一个列表最多包含 2 ^ 32 -1 个元素。
@Service
public class RedisService {
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* set redis:list类型
* @param key key
* @param value value
* @return
*/
public long setList(String key, String value){
ListOperations<String, String> listOperations = stringRedisTemplate.opsForList();
return listOperations.leftPush(key, value);
}
/**
* get redis:list类型
* @param key key
* @param start start
* @param end end
* @return
*/
public List<String> getList(String key, long start, long end){
return stringRedisTemplate.opsForList().range(key, start, end);
}
}
可以看出,这些 api 都是一样的形式,方便记忆也方便使用。具体的 api 细节我就不展开了,大家可以自己看 api 文档。其实,这些 api 根据参数和返回值也能知道它们是做什么用的。来测试一下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class Course14ApplicationTests {
private static final Logger logger = LoggerFactory.getLogger(Course14ApplicationTests.class);
@Resource
private RedisService redisService;
@Test
public void contextLoads() {
//测试redis的list类型
redisService.setList("list", "football");
redisService.setList("list", "basketball");
List<String> valList = redisService.getList("list",0,-1);
for(String value :valList){
logger.info("list中有:{}", value);
}
}
}
本节主要介绍了 redis 的使用场景、安装过程,以及 Spring Boot 中集成 redis 的详细步骤。在实际项目中,通常都用 redis 作为缓存,在查询数据库的时候,会先从 redis 中查找,如果有信息,则从 redis中取;如果没有,则从数据库中查,并且同步到 redis 中,下次 redis 中就有了。更新和删除也是如此,都需要同步到 redis。redis 在高并发场景下运用的很多。
学废了嗷~~