缓存是分布式系统中的重要组件,主要解决数据库数据的高并发访问问题。
Spring Boot 默认缓存管理
Spring框架支持透明地向应用程序添加缓存并对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法中,从来减少操作数据的次数,同时不会对程序本身造成任何干扰。 项目搭建 对应数据库见SpringBoot整合JPA
@Entity ( name= "comment" )
public class Comment {
@Id
@GeneratedValue ( strategy = GenerationType. IDENTITY)
private Integer id;
private String content;
private String author;
private String articleId;
@Override
public String toString ( ) {
return "Comment{" +
"id=" + id +
", content='" + content + '\'' +
", author='" + author + '\'' +
", articleId='" + articleId + '\'' +
'}' ;
}
public Integer getId ( ) {
return id;
}
public void setId ( Integer id) {
this . id = id;
}
public String getContent ( ) {
return content;
}
public void setContent ( String content) {
this . content = content;
}
public String getAuthor ( ) {
return author;
}
public void setAuthor ( String author) {
this . author = author;
}
public String getArticleId ( ) {
return articleId;
}
public void setArticleId ( String articleId) {
this . articleId = articleId;
}
}
public interface CommentRepository extends JpaRepository < Comment, Integer> {
@Transactional
@Modifying
@Query ( "UPDATE comment c set c.author= ?1 where c.id=?2" )
public int updateComment ( String author, Integer id) ;
}
@Service
public class CommentService {
@Autowired
private CommentRepository commentRepository;
public Comment findById ( int comment_id) {
Optional< Comment> optional = commentRepository. findById ( comment_id) ;
return optional. orElse ( null) ;
}
public Comment updateComment ( Comment comment) {
commentRepository. updateComment ( comment. getAuthor ( ) , comment. getId ( ) ) ;
return comment;
}
public void deleteComment ( int comment_id) {
commentRepository. deleteById ( comment_id) ;
}
}
@RestController
public class CommentController {
@Autowired
private CommentService commentService;
@GetMapping ( "/get/{id}" )
public Comment findById ( @PathVariable ( "id" ) int comment_id) {
Comment comment = commentService. findById ( comment_id) ;
return comment;
}
@GetMapping ( "/update/{id}/{author}" )
public Comment updateComment ( @PathVariable ( "id" ) int comment_id, @PathVariable ( "author" ) String author) {
Comment comment = findById ( comment_id) ;
comment. setAuthor ( author) ;
Comment updateComment = commentService. updateComment ( comment) ;
return updateComment;
}
@GetMapping ( "/delete/{id}" )
public void deleteComment ( @PathVariable ( "id" ) int comment_id) {
commentService. deleteComment ( comment_id) ;
}
}
配置文件:
spring.datasource.url=jdbc:mysql://localhost:3306/springdata?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=admin
#jpa 命名:开启无修改命名,该处因为我的数据库没有采用_的写法,所以需采用第一种无修改命名
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# 显示使用JPA进行数据库查询的SQL语句
spring.jpa.show-sql=true
效果: 发现每刷新一次,控制台会新输出一条SQL语句(未开启缓存管理)
Spring Boot 默认缓存体验
@EnableCaching
@SpringBootApplication
public class Chapter06Application {
public static void main ( String[ ] args) {
SpringApplication. run ( Chapter06Application. class , args) ;
}
}
@Service
public class CommentService {
@Autowired
private CommentRepository commentRepository;
@Cacheable ( cacheNames= "comment" )
public Comment findById ( int comment_id) {
Optional< Comment> optional = commentRepository. findById ( comment_id) ;
return optional. orElse ( null) ;
}
. . . .
}
效果示意:刷新页面,发现控制台不会继续输出数据库语句,即默认缓存支持已经生效。
Spring Boot缓存注解介绍
@EnableCaching注解
该注解由Spring框架提供,该注解需要配置在类上(SpringBoot中通常配置在项目启动类上),用于开启基于注解的缓存支持 @Cacheable注解
该注解由Spring框架提供,可以作用于类或者方法(通常用在数据查询方法上),用于对方法的查询结果进行缓存存储。 该注解的执行顺序是:先进行缓存查询,如果为空则进行方法查询,并将结果进行缓存;如果缓存中有数据,不进行方法查询,而是直接使用缓存查询。 该注解提供了多个属性:
value/cacheNames 指定缓存空间的名称,必配属性。可以同时指定多个名称空间(@Cacheable(cacheNames={“comment1”,“comment2”})),如果只指定一个名称空间,那么属性名可以省略,即@Cacheable(“comment”)制定了缓存的名称空间为comment key 指定缓存数据的key,默认使用方法参数值,可以使用SpEL表达式,即为指定缓存数据对应的唯一标识。缓存数据的本质是Map类型数据,key用于指定唯一的标识,value用于指定缓存的数据。 keyGenerator属性 指定缓存数据的key生成器,与key属性二选一使用,指定的是生成器规则而非具体key值 cacheManager/cacheResolver 分别用于指定缓存管理器和缓存解析器,二选一,默认不需要配置,如果存在多个缓存管理器(如redis、Ehcache等),可以使用这两个属性分别指定。 condition condition属性用于对数据进行有条件的选择性存储,如@Cacheable(cacheNames=“comment”,condition="#comment_id>10")表示方法参数comment_id的值大于10才会对结果数据进行缓存。 unless unless属性的作用与condition属性作用相反 sync 表示数据缓存过程中是否使用异步模式,默认为false
@CachePut注解
该注解由Spring框架提供,可以作用于类或方法(通常用在数据更新方法上),该注解作用为更新缓存数据。 该注解的默认执行顺序是:先进行方法调用,然后将方法结果更新到缓存中。 该注解也提供了很多属性,与@Cacheable注解的属性完全相同。 @CacheEvict注解
该注解由Spring框架提供,可以作用于类或方法(通常用在数据删除方法上),该注解的作用是删除缓存数据。 该注解的默认执行顺序是:先进行方法调用,然后清除缓存。 除与@Cacheable注解相同的属性外,还提供了两个特殊属性
allEntries 表示是否清除指定缓存空间中的所有缓存数据,默认值为false(默认只删除指定key对应的缓存数据),如@CacheEvict(cacheNames=“comment”,allEntries=true)表示方法执行后会删除缓存空间comment中所有的属性。 beforeInvocation 表示是否在方法执行之前进行缓存清除,默认值为false(即默认在执行方法后在进行缓存清除),如@CacheEvict(cacheNames=“comment”,beforeInvocation=true)表示在方法执行之前进行缓存清理。需要注意的是,如果该值设置为true,会存在一定弊端。如果在进行数据删除的方法中发生了异常,这回导致数据并没有被删除但是缓存数据却被提前清除了
@Caching注解
处理复杂规则的数据缓存使用@Caching注解,作用于类或者方法,包含cacheable/put/evict三个属性,作用如上三个属性。 @Caching(cacheable={@Cacheable(cacheNames="comment",key="#id")},put={@CachePut(cacheNames="comment",key="#result.author")})
@CacheConfig注解
该注解作用于类,用于统筹管理如@Cacheable、@CachePut、@CacheEvict注解标注的方法中的公共属性,包括cacheNames、keyGenerator、cacheManager、cacheResolver 属性值定义相同,会使用就近原则。