- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
本章给大家带来的是SpringBoot和缓存的学习。同时已经录制了非常详细的视频,如果看文档较为吃力,可以结合视频进行学习,帮你快速掌握SringBoot与缓存。
目录
一、JSR107
二、Spring缓存抽象
三、几个重要概念&缓存注解
四、缓存使用
五、整合redis实现缓存
六、整合一个实例
一、JSR107
Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
CachingProvider 定义了创建、配置、获取、管理和控制多个 CacheManager 。一个应用可以在运行期访问多个 CachingProvider 。
CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache ,这些 Cache 存在于 CacheManager 的上下文中。一个 CacheManager 仅被一个 CachingProvider 所拥有。
Cache 是一个类似 Map 的数据结构并临时存储以 Key 为索引的值。一个 Cache 仅被一个 CacheManager 所拥有。
Entry 是一个存储在 Cache 中的 key-value 对。
Expiry 每一个存储在 Cache 中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过 ExpiryPolicy 设置。
肝完了,总结了SpringBoot与缓存的知识点,快速掌握
二、Spring缓存抽象
Spring从3.1开始定义了
org.springframework.cache.Cache
和
org.springframework.cache.CacheManager接口来统一不同的缓存技术;
并支持使用JCache(JSR-107)注解简化我们的开发;
Cache 接口为缓存的组件规范定义,包含缓存的各种操作集合;
Cache 接口下 Spring 提供了各种 xxxCache 的实现;如 RedisCache , EhCacheCache , ConcurrentMapCache 等;
每次调用需要缓存功能的方法时, Spring 会检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
使用 Spring 缓存抽象时我们需要关注以下两点;
1、确定方法需要被缓存以及它们的缓存策略
2、从缓存中读取之前缓存存储的数据
肝完了,总结了SpringBoot与缓存的知识点,快速掌握
三、几个重要概念&缓存注解
肝完了,总结了SpringBoot与缓存的知识点,快速掌握
肝完了,总结了SpringBoot与缓存的知识点,快速掌握
SpEL语法的缓存格式
肝完了,总结了SpringBoot与缓存的知识点,快速掌握
四、缓存使用
• 1 、引入 spring-boot-starter-cache 模块
• 2 、 @ EnableCaching 开启缓存
• 3 、使用缓存注解
• 4 、切换为其他缓存
测试缓存对象:
五、整合redis实现缓存
\1. 引入 spring-boot-starter-data- redis 、 spring-data- redis
redis.clients
jedis
\2. 配置redis连接地址spring.redis.host=192.168.0.108
\3. 使用ReditTemplate操作redis
\1. redisTemplate.opsForValue ();// 操作字符串
\2. redisTemplate.opsForHash ();// 操作 hash
\3. redisTemplate.opsForList ();// 操作 list
\4. redisTemplate.opsForSet ();// 操作 set
\5. redisTemplate.opsForZSet ();// 操作有序 set
redisconfig实现:
@Configurationpublic class RedisConfig
{
//过期时间private Duration timeToLive = Duration.ofDays(1);
@Beanpublic RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory)
{
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(timeToLive).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())).disableCachingNullValues();
RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).cacheDefaults(configuration).transactionAware().build();
return redisCacheManager;
@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException
{
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(keySerializer());
template.setHashKeySerializer(keySerializer());
template.setValueSerializer(valueSerializer());
template.setHashValueSerializer(valueSerializer());
return template;
private RedisSerializer keySerializer()
{
return new StringRedisSerializer();
private RedisSerializer valueSerializer()
{
return new GenericJackson2JsonRedisSerializer();
application.properties的配置:
spring.datasource.username=springspring.datasource.password=spring
#开启驼峰命名匹配规则mybatis.configuration.map-underscore-to-camel-case=truelogging.level.com.dahaiwuliang.cache.mapper=debug
#redis连接spring.redis.host=192.168.0.108
六、整合一个实例
肝完了,总结了SpringBoot与缓存的知识点,快速掌握
controller层:
@RestControllerpublic class EmployeeController
{
@AutowiredEmployeeService employeeService;
@GetMapping(“/getEmployee”)
public Employee getEmployee(Integer id)
{
Employee employee = employeeService.getEmp(id);
return employee;
@GetMapping(“/updateEmployee”)
public Employee update(Employee employee)
{
Employee emp = employeeService.updateEmp(employee);
return emp;@GetMapping(“/deleteEmployee”)
public String deleteEmp(Integer id)
{
employeeService.deleteEmp(id);
return “success”;
@GetMapping(“/emp/{lastName}”)
public Employee getEmployeeByLastName(
@PathVariable(“lastName”) String lastName)
{
return employeeService.getEmployeeByLastName(lastName);
service层:
public Employee getEmp(Integer id)
{
System.out.println(“查询”+id+“员工”);
Employee employee = employeeMapper.getEmpById(id);
Cache cache = cacheManager.getCache(“emp”);
cache.put(“emp:”+id,employee);return employee;*
@CachePut:既调用方法,又更新缓存* 修改了数据库的数据,并同时更新缓存* 运行机制:* 1、先调用目标方法;* 2、将目标方法的结果缓存起来
@CachePut(/value = “emp”,/key=“#result.id”)
public Employee updateEmp(Employee employee)
{
System.out.println(“update:”+employee);
employeeMapper.updateEmp(employee);
return employee;*
@CacheEvict:清除缓存* allEntries=true清空这个缓存中的所有数据* beforeInvocation=true代表清空缓存操作是在方法执行前就执行了,无论方法是否出现异常,缓存都会被清除
@CacheEvict(/value = “emp”,/key = “#id”/,allEntries = true/,beforeInvocation = true)
public void deleteEmp(Integer id){System.out.println(“deletEmp:”+id);
//employeeMapper.deleteEmpById(id);
int a = 10/0;*
@Caching 定义复杂的缓存规则
@Caching(cacheable = {
@Cacheable(/value = “emp”,/key = “#lastName”)
},
put = {
@CachePut(/value = “emp”,/key = “#result.id”)
public Employee getEmployeeByLastName(String lastName)
{
System.out.println(“getEmployeeByLastName:”+lastName);
return employeeMapper.getEmpByLastName(lastName);
好了,讲解结束,小伙伴们点赞、收藏、评论,一键三连走起呀,下期见~
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在尝试理解 promise ,在本例中是在一个循环中。 我的场景基于将文件上传到 Google 云端硬盘。我的理解是,每个文件都应该上传,然后一旦 promise 得到解决,就上传下一个文件,依此
JDK 1.6 包括通过 JAX-WS API 使用 FastInfoset Web 服务的功能。这些的实现隐藏在 com.sun.xml.internal 的深处,包名旨在让任何明智的 Java 开
我正在学习 React 并思考组件的结构。以下内容让我有些困惑。 我们被告知应该有单一的真相来源。 所有者组件应将 props/状态传递给它的责任(有些人称为“ownee”)组件。 所以,如果我自己的
我刚刚开始使用 Google Guice 作为依赖项注入(inject)框架,并试图将其改造为我最近编写的中小型项目。我了解 Guice 工作原理的基础知识,但对一些方法细节有点模糊。例如: 1) 模
上周我们在上周左右的修补和测试后将 Omniture 的分析代码发布到大量网站上。 在我们几乎所有的网站模板上,它都运行良好。在一些零星的、不可预测的情况下,严重的浏览器崩溃体验可能会让一些用户望而却
我刚刚获得了一个 API,它似乎比我习惯的更上一层楼,因为一切似乎都是使用接口(interface)实现的,我正在努力理解它们。 public partial class Form1 : Form,
我的程序似乎很合我意。但是,当我编译它时,我收到了这条消息: Note: Program.java uses unchecked or unsafe operations. Note: Recompi
最近开始用story board、Xcode等学习Swift。我很难理解 ViewController 代码的原理,因为它似乎遗漏了很多基本要素——大概是为了尝试让事情变得更简单——但它不适合来自其他
我刚收到一些有关使用 wpf、c# 的 MVVM 的设计/实现问题。我只是想掌握 MVVM,如果有人能证实我的想法,我正在徘徊,在我的应用程序中,我需要一名员工、一个部门和一家公司。所以换句话说,我有
我在 gird View 中有一个 gridview 和 2 个链接按钮,编辑和删除,单击编辑按钮 s 时,该行的详细信息应显示在“detailsview”中。我的详细信息 View 在更新面板。 最
function def() { console.log(this.x) } var f = def.bind({ x:777 }) f() // prints 777 bind 创建了一个函
我尝试将谷歌地图(外部加载的脚本)添加到 meteor 应用程序,但没有成功,我注意到有两种问题: 如果我做简单的事情并将主要的 API 脚本添加到我的 ,然后它被呈现为last。 发生这种情况时,
如果我理解正确,Node JS 是非阻塞的......所以它不是等待来自数据库或其他进程的响应,而是转移到其他东西并稍后再检查。 它也是单线程的。 这是否意味着给定的 Node JS 进程可以充分有效
几周前,我开始了 Iphone 应用程序开发的研究,在不同设置中进行了大量的 hello world 应用程序之后,我现在已经准备好开发我的第一个基于 Cocoa 中使用的 MVC 设计模式的应用程序
这个问题和我之前的问题很相似。 大约 4 年前,我在 Visual Studio 2005 中使用过 ASP .Net。恢复最新版本需要多长时间? 最佳答案 这取决于您“使用”它的程度。有经验的开发人
如何让这个程序让用户一次输入 5 位数字,而不是每次都询问单独的数字?我知道我必须使用 string.split() 但我将在哪里放置代码并执行代码。 Heading from random impo
因此,根据我的理解,在 3nf 数据库中,主键值可用于确定表中的每个其他属性。 这是否意味着外键将专门用于创建复合实体?外键如何适合 3nf 数据库? 有哪些“迹象”表明我的数据库已标准化?数据库中的
如何解决以下 f(n)=n!据我所知不适用于主定理的任何情况。T(n) = 16T(n/4) + n! 最佳答案 David Eisenstat 部分正确。情况 3 确实适用,但 T(n) = the
在过去的 2.5 年里,我一直在研究 SAP 技术。由于技术概念太多,我无法找到一个可以了解与它相关的所有内容的单一来源。我没有掌握掌握所有技术概念的信心。 如果您遇到过这样的经历以及如何克服它,请帮
我是一名优秀的程序员,十分优秀!