SpringBoot 使用内置缓存代码详解(数据从缓存中存、取代码讲解)@Cacheable、@CachePut注解讲解
- 项目目录结构如下:
- 引入相关依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- yml配置:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
username: user
password: 123456
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- 实体类Book.java
import lombok.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
private String id;
private String name;
private String description;
private Float price;
}
- 数据层BookDao.java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot.entity.Book;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
- 业务层BookService.java和BookServiceImpl.java
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.springboot.entity.Book;
public interface BookService extends IService<Book> {
Book getCacheById(String id);
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.dao.BookDao;
import com.example.springboot.entity.Book;
import com.example.springboot.service.BookService;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements BookService {
@Override
@Cacheable(value="cacheSpace", key="#id")
public Book getCacheById(String id) {
return getById(id);
}
}
- 表现层BookController.java
import com.example.springboot.entity.Book;
import com.example.springboot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("{id}")
public Book getById(@PathVariable String id){
return bookService.getCacheById(id);
}
}
- 启动项目后通过 Postman 测试
- 将控制台的日志清空,再次通过Postman 请求数据:
- 由此可见,已缓存的数据不会再次请求数据库,直接从缓存中取。
- @Cacheable和@CachePut注解的区别:
- @Cacheable:标记在一个方法上时表示该方法是支持缓存的,Spring会在方法被调用后将其返回值缓存起来,下次用同样的参数来执行该方法时可以直接从缓存中获取结果。
@CachePut:标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将该方法的返回值放到缓存中。
数据从缓存中存、取代码讲解:
- 缓存中存、取数据:
@Cacheable(value="cacheSpace", key="#id")
public Book getCacheById(String id) {
return getById(id);
}
- 在上述代码中,@Cacheable注解和 return 一起使用可以将返回值存储到缓存中(注意:return 不能返回 null )。同时,下次用同样的参数来执行该方法时可以直接从缓存中获取结果。
- 缓存中存数据
@CachePut(value="cacheSpace", key="#id")
public Book getCacheById(String id) {
return getById(id);
}
- 在上述代码中,@CachePut 注解用于将返回值存储到缓存中,这个注解不会从缓存中取数据,只能存储数据。
- 缓存中取数据
@Cacheable(value="cacheSpace", key="#id")
public Book getCacheData(String id) {
return null;
}
- 在上述代码中,@Cacheable 注解和 return null 一起使用,用于在缓存中读取数据。
- 注意 getCacheData() 要以 Bean 的形式去调用,不能放到实现类的方法中,即如下图展示的,不会去走注解,直接是方法调用,从而引发空指针异常。
- 以 Bean 的形式去调用 getCacheData()
import com.example.springboot.entity.Book;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class CacheUtil {
@Cacheable(value="cacheSpace", key="#id")
public Book getCacheData(String id){
return null;
}
}
- 使用Postman测试结果如下:
-
先执行 GET 请求,将相关数据放到缓存中: -
在执行 POST 请求做校验:
|