一. 搭建一个maven工程:
- 主体框架: SpringBoot-2.7.17, Mybatis-Plus,Druid连接池;
- 工具: IDEA2023;
- Java版本: 1.8;
1. pom.xml所用依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2. 配置Application.yml:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/数据库名
username: 账号
password: 密码
data:
redis:
host: 127.0.0.1
port: 6379
username: *zhanghao*
password: *mima1*
database: 0
lettuce:
pool:
max-active: 20
max-wait: -1
min-idle: 0
max-idle: 5
mybatis:
configuration:
log-impl: org.apache.log4j.Logger
mapper-locations: classpath:mapper/*.xml
3. 创建&配置App启动类:
@SpringBootApplication
@EnableCaching
public class testApp {
public static void main(String[] args) {
SpringApplication.run(testApp.class, args);
}
}
二. 搭建大体框架:
1. Controller层:
@RestController
@RequestMapping("/test")
public class UserController
@Resource
private RedisService redisService;
@GetMapping("/readRedis")
public R<User> redisTest(){
return new R<>(2000, "缓存读取成功!", redisService.rmCache());
}
}
2. Service层:
public interface RedisService extends IService<User> {
User readCache();
}
3. ServiceImpl层:
- 做一个假数据用于Api调用测试;
@Service("redisServiceImpl")
public class RedisServiceImpl extends ServiceImpl<RedisServiceMapper, User> implements RedisService {
static Logger log = Logger.getLogger(RedisServiceImpl.class);
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private RedisServiceMapper redisServiceMapper;
@Override
@Cacheable(value = "userCache", key = userId)
@Transactional
public User readCache() {
User user = new User();
user.setId(3);
user.setUserName("strong");
user.setPassWord("777777");
user.setCreateTime(new DateTime());
user.setUpdateTime(new DateTime());
try {
saveOrUpdate(user);
redisTemplate.opsForHash().put("user", user.getId(), user);
log.info("待更新缓存" + redisTemplate.opsForHash().get("user", user.getId()));
log.info("缓存更新成功!");
return (User) redisTemplate.opsForHash().get("user", 3);
} catch (Exception e) {
log.error("缓存更新失败: " + e.getMessage(), e);
throw new RuntimeException(e);
}
}
}
4. Mapper层:
@Mapper
public interface RedisServiceMapper extends BaseMapper<User> {
}
5. Domain实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User implements Serializable {
private static final long serialVersionUID = -6437445357327699086L;
@TableId("id")
private Integer id;
@TableField("username")
private String userName;
@TableField("password")
private String passWord;
}
三. ApiPost/PostMan调用接口测试:
1. 使用@CacheAble:
@Cacheable对其进行注解,它会将方法返回结果存储在注解指定的缓存中:- 使用
@Cacheable在这种情况下,如果缓存中包含所需的结果,就会返回该结果,而不会调用该方法。
调用返回数据:
{
"code": 2000,
"msg": "缓存读取成功!",
"data": {
"id": 3,
"userName": "strong",
"passWord": "777777",
}
}
2. 使用@CacheEvict:
- 缓存的数据如果不进行清理,会保留大量陈旧或未使用甚至是过期的数据。
- 使用
@CacheEvict注解来删除一个、多个或所有的值,以刷新缓存:
1. 新增代码:
-
Controller层:
@GetMapping("/rmCache")
public R<String> rmCache(){
return new R<>(2000, "缓存删除成功!", redisService.rmCache());
}
-
ServiceImpl层:
@Override
@CacheEvict(value = "user", key = "0")
public String rmCache() {
return "删除缓存成功!";
}
调用返回结果:
{
"code": 2000,
"msg": "缓存删除成功!",
"data": "删除缓存成功!"
}
3. 使用@CachePut
@Cacheable和@CachePut的区别在于,@Cacheable会跳过运行方法,而@CachePut会运行方法,然后将结果放入缓存。
1. 新增代码
-
Controller层:
@GetMapping("/putCache")
public R<User> putCache(){
return new R<>(2000, "缓存写入成功!", redisService.putCache());
}
-
ServiceImpl层:
@Override
@Transactional
@CachePut(value = "userCache")
public User putCache() {
User user = new User();
user.setId(3);
user.setUserName("strong");
user.setPassWord("777777");
user.setCreateTime(new DateTime());
user.setUpdateTime(new DateTime());
try {
saveOrUpdate(user);
redisTemplate.opsForHash().put("user", user.getId(), user);
log.info("待更新缓存" + redisTemplate.opsForHash().get("user", user.getId()));
log.info("缓存更新成功!");
return (User) Objects.requireNonNull(redisTemplate.opsForHash().get("user", user.getId()));
} catch (Exception e) {
log.error("缓存更新失败: " + e.getMessage(), e);
throw new RuntimeException(e);
}
}
调用返回数据:
{
"code": 2000,
"msg": "缓存读取成功!",
"data": {
"id": 3,
"userName": "strong",
"passWord": "777777",
}
}
4.总结:
- 在SpringBoot工程项目中使用
事务控制的方法进行数据一致性操作; - 数据先执行插入数据库操作,对数据库更新成功后再更新Redis的缓存数据;
- 搭配上Spring的Cache依赖,这种方法简单易用。