Dalam SpringBoot, pengurusan cache dan penyimpanan data bergantung pada antara muka pengurus cache org.springframework.cache.Cache dan org.springframework.cache.CacheManager yang berkaitan dengan cache dalam Rangka kerja musim bunga.
Jika tiada komponen Bean jenis CacheManager atau penyelesai cache CacheResolver bernama cacheResolver yang ditakrifkan dalam program, SpringBoot akan cuba memilih dan mendayakan komponen cache berikut (dalam susunan yang ditentukan):
( 1) Generik
(2) JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, dll.)
(3) EhCache 2.x
(4) Hazelcast
(5) Infinispan
(6) Couchbase
(7) Redis
(8) Kafein
(9) Mudah
Di atas menyenaraikan 9 komponen cache yang disokong oleh SpringBoot mengikut susunan pemuatan komponen cache SpringBoot Selepas menambah komponen pengurusan cache (seperti Redis) pada projek, projek SpringBoot akan memilih dan dayakan peranti pengurusan cache yang sepadan. Jika berbilang komponen cache ditambahkan pada projek pada masa yang sama, dan tiada pengurus cache atau penyelesai cache (CacheManager atau cacheResolver) ditentukan, SpringBoot akan mendayakan komponen pertama antara berbilang komponen cache yang ditambahkan dalam susunan di atas pengurusan cache (contohnya, jika dua komponen cache Couchbase dan Redis ditambah pada masa yang sama, maka komponen Couchbase didayakan dahulu).
Dalam pengurusan cache lalai yang diperkenalkan dalam artikel sebelumnya SpringBoot Cache Management (1) Default Cache Management, projek yang kami bina tidak menambah sebarang komponen pengurusan cache, tetapi pengurusan cache masih dilaksanakan. Ini kerana selepas pengurusan cache didayakan, SpringBoot akan mencari komponen cache yang sah untuk pengurusan cache mengikut susunan komponen cache di atas Jika tiada komponen cache, komponen cache Mudah terakhir akan digunakan secara lalai untuk pengurusan . Komponen cache mudah ialah komponen pengurusan cache lalai SpringBoot Ia menggunakan ConcurrentMap dalam memori untuk penyimpanan cache secara lalai, jadi anda masih boleh mencapai pengurusan cache dalam ingatan tanpa menambah sebarang komponen cache pihak ketiga, tetapi ia tidak disyorkan. Kaedah pengurusan cache ini.
Perkenalkan komponen cache Redis berdasarkan projek yang dibina oleh SpringBoot Cache Management (1) Pengurusan Cache Lalai, dan gunakan kaedah berasaskan anotasi untuk menerangkan butiran khusus penyepaduan SpringBoot bagi Redis cache capai.
(1) Tambah pemula pergantungan Spring Data Redis
Tambah pemula pergantungan Spring Data Redis dalam fail pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
Apabila kami menambah kebergantungan berkaitan Redis Selepas pelancar, SpringBoot akan menggunakan RedisCacheConfigratioin sebagai kelas konfigurasi automatik untuk melaksanakan kelas pemasangan automatik berkaitan cache (sebelum ini SimpleCacheConfiguration lalai yang digunakan dalam bekas menjadi RedisCacheManager (sebelum ini pengurus cache lalai ini mencipta Cache ialah RedisCache). , yang mengawal Redis ke cache data.
(2) Konfigurasi sambungan pelayan Redis
Tambah konfigurasi sambungan pangkalan data Redis dalam aplikasi fail konfigurasi global.Properties contoh kod adalah seperti berikut:
# Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password=
(3) Ubah suai kaedah dalam kelas CommentService
Gunakan tiga anotasi @Cacheable, @CachePut dan @CacheEvict untuk pengurusan cache dan lakukan operasi seperti storan cache, kemas kini cache dan pemadaman cache masing-masing:
package com.hardy.springbootdatacache.service; import com.hardy.springbootdatacache.entity.Comment; import com.hardy.springbootdatacache.repository.CommentRepository; 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 java.util.Optional; /** * @Author: HardyYao * @Date: 2021/6/19 */ @Service public class CommentService { @Autowired private CommentRepository commentRepository; /** * 根据评论id查询评论 * @Cacheable:将该方法的查询结果comment存放在SpringBoot默认缓存中 * cacheNames:起一个缓存命名空间,对应缓存唯一标识 * @param id * @return */ @Cacheable(cacheNames = "comment", unless = "#result==null") public Comment findCommentById(Integer id){ Optional<Comment> comment = commentRepository.findById(id); if(comment.isPresent()){ Comment comment1 = comment.get(); return comment1; } return null; } /** * 更新评论 * @param comment * @return */ @CachePut(cacheNames = "comment",key = "#result.id") public Comment updateComment(Comment comment) { commentRepository.updateComment(comment.getAuthor(), comment.getaId()); return comment; } /** * 删除评论 * @param comment_id */ @CacheEvict(cacheNames = "comment") public void deleteComment(int comment_id) { commentRepository.deleteById(comment_id); } }
Dalam kod di atas, anotasi @Cacheable, @CachePut dan @CacheEvict digunakan untuk melaksanakan pengurusan cache pada pertanyaan data, kemas kini data dan kaedah pemadaman data.
Antaranya, tiada nilai kunci bertanda dalam cache pertanyaan @ anotasi Cacheable, dan nilai parameter lalai comment_id akan digunakan sebagai kunci untuk menyimpan data Kunci yang sama mesti digunakan semasa mengemas kini cache ; begitu juga, apabila menggunakan cache pertanyaan Dalam anotasi @Cacheable, melainkan= "#result==null" ditakrifkan untuk menunjukkan bahawa hasil pertanyaan tidak akan dicache jika ia kosong.
(4) Tambah dua antara muka baharu pada kelas CommentController
Tambah kemas kini dan padam antara muka:
package com.hardy.springbootdatacache.controller; import com.hardy.springbootdatacache.entity.Comment; import com.hardy.springbootdatacache.service.CommentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author: HardyYao * @Date: 2021/6/19 */ @RestController public class CommentController { @Autowired private CommentService commentService; @RequestMapping(value = "/findCommentById") public Comment findCommentById(Integer id){ Comment comment = commentService.findCommentById(id); return comment; } @RequestMapping(value = "/updateComment") public Comment updateComment(Comment comment){ Comment oldComment = commentService.findCommentById(comment.getId()); oldComment.setAuthor(comment.getAuthor()); Comment comment1 = commentService.updateComment(oldComment); return comment1; } @RequestMapping(value = "/deleteComment") public void deleteComment(Integer id){ commentService.deleteComment(id); } }
(5) Ujian cache pertanyaan Redis berasaskan anotasi
Masukkan dalam penyemak imbas: http://localhost:8080/findCommentById?id=1 untuk mengakses:
Halaman melaporkan ralat, semak maklumat konsol :< . laksanakan serialisasi (DefaultSerializer memerlukan muatan Serializable tetapi menerima objek jenis [com.hardy.springbootdatacache.entity.Comment]).
(6) Serikan objek cache
(7) Mulakan semula projek untuk menguji cache pertanyaan
在浏览器中输入:http://localhost:8080/findCommentById?id=1 进行访问(连续访问三次):
打开Redis客户端可视化工具Redis Desktop Manager,连接本地启用的Redis服务,查看具体的数据缓存效果:
执行findById()方法查询出的用户评论信息Comment正确存储到了Redis缓存库中名为comment的名称空间下。
其中缓存数据的唯一标识key值是以“名称空间comment::+参数值(comment::1)”的字符串形式体现的,而value值则是经过JDK默认序列格式化后的HEX格式存储。这种JDK默认序列格式化后的数据显然不方便缓存数据的可视化查看和管理,所以在实际开发中,通常会自定义数据的序列化格式,这方面的内容在后面会介绍。
(8)基于注解的Redis缓存更新测试
先通过浏览器访问:http://localhost:8080/updateComment?id=1&author=hardy;
接着在访问:http://localhost:8080/findCommentById?id=1,查看浏览器返回信息及控制台打印信息:
可以看到,执行updateComment()更新id为1的数据时执行了一条更新的SQL语句,后续调用findById()方法查询id为1的用户评论信息时没有再次执行查询的SQL语句,且浏览器返回了更新后的正确结果,这说明@CachePut缓存更新配置成功。
(9)基于注解的Redis缓存删除测试
通过浏览器访问:http://localhost:8080/deleteComment?id=1 和 http://localhost:8080/findCommentById?id=1
执行deleteComment()方法删除id为1的数据后查询结果为空,查看Redis缓存数据库:
可以看到之前存储的comment相关数据被删除掉了,这表明@CacheEvict注解缓存删除成功实现。
通过上面的案例可以看出:使用基于注解的Redis缓存实现只需要添加Redis依赖、并使用几个注解在对应的方法上,就可以实现对数据的缓存管理。
另外,还可以在SpringBoot全局配置文件中配置Redis有效期,示例代码如下:
# 对基于注解的Redis缓存数据统一设置有效期为1分钟,单位毫秒 spring.cache.redis.time-to-live=60000
上述代码中,在SpringBoot全局配置文件中添加了“spring.cache.redis.time-to-live”属性统一设置Redis数据的有效期(单位为毫秒),但这种方式不够灵活,因此一般不用。
在SpringBoot整合Redis缓存实现中,除了基于注解形式的Redis缓存形式外,还有一种开发中更常用的方式——基于API的Redis缓存实现。这种基于API的Redis缓存实现,需要在某种业务需求下通过Redis提供的API调用相关方法实现数据缓存管理。同时,这种方法还可以手动管理缓存的有效期。
下面,通过Redis API的方式讲解SpringBoot整合Redis缓存的具体实现。
(1)使用Redis API进行业务数据缓存管理
在 com.hardy.springbootdatacache.service 包下新建一个 ApiCommentService:
package com.hardy.springbootdatacache.service; import com.hardy.springbootdatacache.entity.Comment; import com.hardy.springbootdatacache.repository.CommentRepository; 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.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.Optional; import java.util.concurrent.TimeUnit; /** * @Author: HardyYao * @Date: 2021/6/19 */ @Service public class ApiCommentService { @Autowired private CommentRepository commentRepository; @Autowired private RedisTemplate redisTemplate; /** * 根据评论id查询评论 * @param id * @return */ public Comment findCommentById(Integer id){ // 先查Redis缓存 Object o = redisTemplate.opsForValue().get("comment_" + id); if (o != null) { return (Comment) o; } else { // 如果缓存中没有,则从数据库查询 Optional<Comment> dbComment = commentRepository.findById(id); if (dbComment.isPresent()) { Comment redisComment = dbComment.get(); // 将查询结果存储到缓存中,并设置有效期为1天 redisTemplate.opsForValue().set("comment_"+id, redisComment,1, TimeUnit.DAYS); return redisComment; } else { return null; } } } /** * 更新评论 * @param comment * @return */ public Comment updateComment(Comment comment) { commentRepository.updateComment(comment.getAuthor(), comment.getId()); // 更新数据库数据后进行缓存更新 redisTemplate.opsForValue().set("comment_" + comment.getId(), comment); return comment; } /** * 删除评论 * @param comment_id */ public void deleteComment(int comment_id) { commentRepository.deleteById(comment_id); // 删除数据库数据后进行缓存删除 redisTemplate.delete("comment_" + comment_id); } }
(2)编写Web访问层ApiCommentController
package com.hardy.springbootdatacache.controller; import com.hardy.springbootdatacache.entity.Comment; import com.hardy.springbootdatacache.service.ApiCommentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author: HardyYao * @Date: 2021/6/19 */ @RestController @RequestMapping("api") // 改变请求路径 public class ApiCommentController { @Autowired private ApiCommentService apiCommentService; @RequestMapping(value = "/findCommentById") public Comment findCommentById(Integer id){ Comment comment = apiCommentService.findCommentById(id); return comment; } @RequestMapping(value = "/updateComment") public Comment updateComment(Comment comment){ Comment oldComment = apiCommentService.findCommentById(comment.getId()); oldComment.setAuthor(comment.getAuthor()); Comment comment1 = apiCommentService.updateComment(oldComment); return comment1; } @RequestMapping(value = "/deleteComment") public void deleteComment(Integer id){ apiCommentService.deleteComment(id); } }
(3)测试基于API的Redis缓存实现
输入:http://localhost:8080/api/findCommentById?id=2(连续输入三次)、http://localhost:8080/api/updateComment?id=2&author=hardy、http://localhost:8080/deleteComment?id=2进行访问:
Lihat mesej konsol dan pangkalan data Redis:
Berkaitan berasaskan API konfigurasi pelaksanaan cache Redis : Pelaksanaan cache Redis berasaskan API tidak memerlukan anotasi @EnableCaching untuk mendayakan sokongan cache berasaskan anotasi, jadi di sini anda boleh memilih untuk memadam atau menganotasi anotasi @EnableCaching yang ditambahkan pada kelas permulaan projek . Ia tidak akan Mempengaruhi pelaksanaan fungsi projek.
Atas ialah kandungan terperinci Bagaimana SpringBoot menyepadukan pelaksanaan cache Redis. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!