redis介绍
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis 本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。
docker安装redis
- 拉取镜像
docker pull redis
- 运行容器
docker run -d --name redis --restart always -p 6379:6379 -v /usr/local/redis/config:/etc/redis -v /usr/local/redis/data:/data redis redis-server /etc/redis/redis.conf --appendonly yes
- docker run:这里指启动容器
- -d:后台模式启动redis
- –name:指定容器名
- –restart always:当服务器重启时,redis的容器也自动启动
- -p 6379:6379:将容器的6379端口映射到宿主机的6379端口
- -v /usr/local/redis/conf:/etc/redis:用于挂载目录,docker镜像redis默认无配置文件,在宿主主机/usr/local/redis/conf下创建redis.conf配置文件,会将宿主机的配置文件复制到docker中
- -v /root/redis/redis01/data:/data:容器/data映射到宿主机 /usr/local/redis/data下
- –appendonly yes:开启redis的AOF持久化,默认为false,不持久化
- 查看正在运行的容器
docker ps
- 进入redis容器里操作
docker exec -it redis redis-cli
5. redis默认有15个库(集群没有),通过select 1 可以切换数据库0~15
select 1
快速集成
- pom.xml文件添加依赖
<!-- 引入redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- application.yml添加redis配置
spring:
redis:
database: 0 # Redis 数据库索引(默认为0)
host: 115.29.149.49 # Redis 服务器地址
port: 6379 # Redis 服务器连接端口
password: # Redis 服务器连接密码(默认为空)
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 10000 # 连接超时时间(毫秒)
自动配置
在项目中引入了 Spring Data Redis ,并且配置了 Redis 的基本信息,此时,自动化配置就会生效。
此刻我们就可以在项目中注入redisTemplate进行使用,可以查看RedisTemplate的自动配置源码,如下:
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
通过源码可以看出Springboot会自动在容器中生成一个RedisTemplate 和StringRedisTemplate ,其中 StringRedisTemplate 是 RedisTemplate 的子类,RedisTemplate 的泛型是<Object,Object>意味着key和value都可以是同一个对象,但写代码不方便需要写很多类型转换,我们需要一个泛型为<String,Object>形式的RedisTemplate。而且,这个RedisTemplate 没有设置数据存在redis时的key和value的序列化方式。
SpringBoot具有天然的开箱即用的特点,那么集成redis也是一样,通过redisTemplate进行操作:
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
注意:
如果没有设置key和value的序列化方式,那么存入数据会乱码一样。
举个小例子:
@RestController
@RequestMapping(value = "/user")
@Api(tags = "UserController", description = "用户管理")
public class UserController {
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping(value = "/getRedis")
public void getRedisValue(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("devin", "药岩");
operations.set("jack", "药尘");
}
}
通过命令查询存入的所有key:
keys *
查询如下图所示:
可以看出Jack和devin前面的字符乱码是因为RedisTemplate 序列化的结果,而RedisTemplate 中key的默认序列化方案是JDK的序列化策略(JdkSerializationRedisSerializer) ,可这在StringRedisTemplate 中,key 默认的序列化方案是 StringRedisSerializer ,因此,如果使用 StringRedisTemplate ,默认情况下 key 前面不会有这种乱码前缀。
自动配置不好用那就重写一下RedisTemplate
创建一个RedisConfig的配置类
/**
* redis 配置类
* @ClassName RedisConfig
* @Author 药岩
* @Date 2020/2/2
* Version 1.0
*/
@Configuration
public class RedisConfig {
private final RedisTemplate redisTemplate;
@Autowired
public RedisConfig(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Bean
@SuppressWarnings("unchecked")
public RedisTemplate<String, Object> redisTemplate(){
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
RedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// key采用String的序列化方式
redisTemplate.setKeySerializer(redisSerializer);
// value的序列化采用jackson
redisTemplate.setValueSerializer(jacksonSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(redisSerializer);
// hash的value也采用jackson
redisTemplate.setHashValueSerializer(jacksonSerializer);
return redisTemplate;
}
}
@SuppressWarnings(“unchecked”) 注解:
告诉编译器忽略指定的警告,屏蔽未检查的转换时的警告
先清空当前的数据库
浏览器再访问:http://localhost:8080/user/getRedis
再次查看存入的数据:
工具为redis客户端
redis客户端下载,解压即可使用
链接:https://pan.baidu.com/s/1ZASHtYKmtECBdmeceItQ3w
提取码:ahp6
编写redis工具类,对常用方法进行封装
在实际的使用过程中,不会给每一个使用的类都注入 redisTemplate 来直接使用,一般都会对业务进行简单的包装,最后提供出来对外使用。
/**
* redis工具类
* @ClassName RedisUtil
* @Author 药岩
* @Date 2020/2/2
* Version 1.0
*/
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 判断key是否存在
* @Author 药岩
* @Date 2020/2/2
* @param * @param key
* @return boolean
*/
public boolean hasKey(String key){
try {
return redisTemplate.hasKey(key);
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @Author 药岩
* @Date 2020/2/2
* @param * @param key
* @return void
*/
public void del(String... key){
if (key != null && key.length > 0){
if (key.length == 1){
redisTemplate.delete(key[0]);
}else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
/**
* 设置缓存失效时间
* @Author 药岩
* @Date 2020/2/2
* @param * @param key
* @param time
* @return boolean
*/
public boolean expire(String key, Long time){
try {
if (time > 0){
redisTemplate.expire(key, time, TimeUnit.MINUTES);
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* String类型 数据存入缓存
* @Author 药岩
* @Date 2020/2/2
* @param * @param key
* @param value
* @return boolean
*/
public boolean set(String key, Object value){
try {
redisTemplate.opsForValue().set(key, value);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* String类型 根据key获取缓存
* @Author 药岩
* @Date 2020/2/2
* @param * @param key
* @return java.lang.Object
*/
public Object get(String key){
return key != null ? redisTemplate.opsForValue().get(key) : null;
}
}
创建一个User对象
/**
* 用户信息
* @ClassName CoinUser
* @Author 药岩
* @Date 2020/2/2
* Version 1.0
*/
public class CoinUser {
private Long id;
private String loginName;
private String password;
private String email;
private String mobile;
public CoinUser() {
}
public CoinUser(String loginName, String password, String email, String mobile) {
this.loginName = loginName;
this.password = password;
this.email = email;
this.mobile = mobile;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRedisTemplate {
@Autowired
private RedisUtil redisUtil;
@Test
public void testRedis(){
CoinUser coinUser = new CoinUser("药岩", "123456", "[email protected]", "1870797****");
redisUtil.set("user", coinUser);
}
}
往redis里面存入一个User对象,启动运行后,通过redis客户端查看
超时失效
将刚刚存入redis中的用户信息,并设置1000毫秒后失效,启动一个线程暂停2000毫秒,再查看redis中的用户信息是否存在。
@Test
public void testRedisExpire() throws InterruptedException {
redisUtil.expire("user", 1000L);
Thread.sleep(2000);
boolean exist = redisUtil.hasKey("user");
if (exist){
System.out.println("用户信息存在");
}else {
System.out.println("用户信息失效");
}
}
控制台打印:
用户信息失效
本篇主要介绍String数据类型,喜欢的点赞+转发就是最大的支持!