Redis - 基于SpringBoot

缓存中间件Redis - 基于SpringBoot

 

缓存中间件Redis - 基于SpringBoot

步骤一、加入Redis相关依赖

步骤二、配置Redis服务器的相关属性

步骤三、开启基于注解的缓存

步骤四、数据对象必须可序列化

步骤五、在相应的方法上加上缓存注解@Cacheable、@CachePut、@CacheEvict

SpEL表达式


步骤一、加入Redis相关依赖

该项目使用springboot 2.4.0版本

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!--Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

引入redis相关的依赖以启用Redis作为项目的缓存,否则Springboot默认使用SimpleCacheConfiguration配置类,启用Springboot内部默认的缓存,该默认缓存使用ConcurrentHashMap缓存数据,而不会使用RedisCacheConfiguration配置类。

注意:

在Springboot1.5.22版本之后,如果要使用RedisTemplate直接对Redis进行操作,需要手动引入jedis。本文使用的demo项目没有使用RedisTemplate对Redis进行操作,所以未引入jedis。

<dependency>
	<groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

PS:spring-boot-starter-data-redis 1.5.22之前的版本中直接引入的jedis,spring-boot-starter-data-redis 1.5.22之后的版本中不再直接引入jedis,而是引入的spring-data-redis。在spring-data-redis中引入了jedis,但是引入的jedis是可选的(optional=true), optional=true的依赖不会在模块之间进行传递。也就是说,如果你的项目使用的是Spring-boot-starter-data-redis1.5.22之后的版本,那么jedis不会出现在项目依赖中。如果需要使用jedis,需要手动引入jedis对应版本的依赖,否则不能通过注入RedisTemplate来操作Redis

步骤二、配置Redis服务器的相关属性

spring:  
  redis:
    host: localhost 
    port: 6379
    password: password1

如果Redis服务器在本地,并且端口是6379,那么host和port不用配置,因为默认的spring.redis.host=localhost,spring.redis.port=6379

步骤三、开启基于注解的缓存

在SpringBoot项目的启动类上加上@EnableCaching注解

步骤四、数据对象必须可序列化

简单的数据对象实现Serializable接口,如下

package com.example.demo.entity;

import java.io.Serializable;

import lombok.Data;

@Data
public class User implements Serializable{

	private Long id;
	
	private String name;
	
	private String address; 
}

复杂的数据对象(如多层调用)需要重写readObject() writeObject()方法

 

步骤五、在相应的方法上加上缓存注解@Cacheable、@CachePut、@CacheEvict

package com.example.demo.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;

@Service
public class UserServiceImpl implements UserService{
	
	private static final String CACHE_USER = "USER";
	
	final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
	
	@Autowired
	UserMapper userMapper;

	@Override
	@Transactional
	@CachePut(cacheNames = CACHE_USER, key = "#user.id", condition = "#result != null") // @CachePut 调用方法并且更新缓存
	public User insert(User user) {
		userMapper.insert(user);
		return user;
	}
	
	@Override
	@Cacheable(cacheNames = CACHE_USER, key = "#id") // @Cacheable 缓存命中则不调用方法,否则调用方法并且更新缓存
	public User getUserById(Long id) {
		logger.info("UserService - getUserById(id = " + id+")");
		return userMapper.getUserById(id);
	}

	@Override
	@Transactional
	@CacheEvict(cacheNames = CACHE_USER, key = "#user.id", condition = "#result != null")
	public User updateUser(User user) {
		logger.info("UserService - updateUser(" + user+")");
		userMapper.updateUser(user);
		return user;
	}

	@Override
	@Transactional
	@CacheEvict(cacheNames = CACHE_USER, key = "#id", condition = "#result > 0")
	public int deleteUserById(Long id) {
		logger.info("UserService - deleteUserById(id = " + id+")");
		return userMapper.deleteUserById(id);
	}

}

在方法上加上注解后,并且配置相关注解的属性。如:cacheNames、key、keyGenerator、condition、unless。

cacheNames:缓存的名字。如上述代码中,将所有关于User的数据缓存到"User"下,也可以理解为:根据不同的数据,将其分组。User相关的数据就缓存到"User"下,Item相关的数据缓存到"Item"下。

key: 键值对中的key。因为数据在Redis中是以key/value的形式存储的,因此需要设置数据缓存键值对中的key。上述代码简单地将user数据对象的id作为key,所以id为1的user在缓存中的key是User::1

keyGenerator:key的生成器,用于自定义key的生成方式。key和keyGenerator指定一个即可。

condition:condition指定一个SpEL表达式,表示是否将方法返回值进行缓存,true则缓存,否则不缓存。

unless:与condition类似,只是表达的意思恰好相反。unless指定一个SpEL表达式,表示是否将方法返回值进行缓存,true则不缓存,否则缓存。

SpEL表达式

名字位置描述示例
methodNameroot object当前被调用的方法名#root.methodName
methodroot object当前被调用的方法#root.method.name
targetroot object当前被调用的目标对象#root.target
targetClassroot object当前被调用的目标对象类#root.targetClass
argsroot object当前被调用的方法的参数列表#root.args[0]
cachesroot object当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cache#root.caches[0].name
argument nameevaluation context方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的形式,0代表参数的索引;#iban 、 #a0 、 #p0
resultevaluation context方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache put’的表达式 ’cache evict’的表达式beforeInvocation=false)#result

 

记录学习Redis,仅供参考,不当之处欢迎指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值