


Wie SpringBoot @Cacheable zum Zwischenspeichern und Abrufen von Werten verwendet
Verwenden Sie @Cacheable für Caching und Wert
1. Die Rolle von @Cacheable
Der Schritt zur Verwendung von Caching besteht darin, Caching mithilfe der Annotation @Cacheable zu implementieren. Wir können also zunächst über die Schritte zur Verwendung des Caches sprechen:
Verwenden Sie die Annotation @EnableCaching in der Hauptstartklasse von SpringBoot, um annotationsbasiertes Caching zu aktivieren.
Markieren Sie einfach die Cache-Annotation
Schritt eins: Aktivieren Sie annotationsbasiertes Caching und markieren Sie es mit @EnableCaching in der Springboot-Hauptstartklasse # 🎜🎜#
//开启基于注解的缓存 @EnableCaching @EnableRyFeignClients @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class ZfjgAuthApplication { public static void main(String[] args) { SpringApplication.run(ZfjgAuthApplication.class, args); } }
@Repository public interface DeviceMapper { @Cacheable(cacheNames = "DeviceDO.deviceId") DeviceDO get(String deviceId); @CacheEvict(cacheNames = "DeviceDO.deviceId", key = "#record.deviceId") int insert(DeviceDO record); }
-
cacheNames
/value
: wird verwendet, um den Namen der Cache-KomponentecacheNames
/value
:用来指定缓存组件的名字 key
:缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)keyGenerator
:key 的生成器。 key 和 keyGenerator 二选一使用cacheManager
:可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。condition
:可以用来指定符合条件的情况下才缓存unless
:否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)sync
- mindestens einer der Caches
trifft, wird der Wert in diesem Cache zurückgegeben.
Beispiel: @Override @Cacheable({"menu", "menuById"}) public Menu findById(String id) { Menu menu = this.getById(id); if (menu != null){ System.out.println("menu.name = " + menu.getName()); } return menu; } --------- @GetMapping("/findById/{id}") public Menu findById(@PathVariable("id")String id){ Menu menu0 = menuService.findById("fe278df654adf23cf6687f64d1549c0a"); Menu menu2 = menuService.findById("fb6106721f289ebf0969565fa8361c75"); return menu0; }
Nach dem Login kopierenSchreiben Sie der Intuition halber den ID-Parameter direkt in den Code. Jetzt testen wir es und sehen uns die Ergebnisse an:
- 3. Schlüssel & Schlüsselgenerator
condition 不指定相当于 true,unless 不指定相当于 false
condition = false,一定不会缓存;
condition = true,且 unless = true,不缓存;
condition = true,且 unless = false,缓存;
key</code anzugeben >: Hiermit kann der Schlüssel angegeben werden, der beim Zwischenspeichern von Daten verwendet wird. Standardmäßig wird der Wert des Methodenparameters verwendet. (Sie können spEL-Ausdrücke verwenden, um diesen Schlüssel zu schreiben) </ul><h3></h3><h4 id="code-keyGenerator-code-Schlüsselgenerator-Verwenden-Sie-entweder-key-oder-keyGenerator"><code>keyGenerator
: Schlüsselgenerator. Verwenden Sie entweder key oder keyGenerator cacheManager
: kann verwendet werden, um den Cache-Manager anzugeben. Von welchem Cache-Manager der Cache bezogen werden soll.
condition
: Kann verwendet werden, um das Caching nur dann anzugeben, wenn Bedingungen erfüllt sind
es sei denn
: Caching negieren. Wenn die durch „außer“ angegebene Bedingung wahr ist, wird der Rückgabewert der Methode nicht zwischengespeichert. Selbstverständlich können Sie sich die Ergebnisse auch zur Beurteilung holen. (Erhalten Sie das Methodenergebnis über #result) sync
: Ob der asynchrone Modus verwendet werden soll.
Bei Verwendung der @Cacheable-Annotation für eine Methode ist dies der Fall Dies bedeutet, dass die von dieser Methode zurückgegebenen Ergebnisse zwischengespeichert werden können. Das heißt, das Rückgabeergebnis dieser Methode wird im Cache abgelegt, sodass bei zukünftigen Aufrufen der Methode mit denselben Parametern der Wert im Cache zurückgegeben wird, ohne dass die Methode tatsächlich ausgeführt wird.
Beachten Sie, dass hier ein Punkt hervorgehoben wird: Die Parameter sind gleich. Dies sollte leicht zu verstehen sein, da sich der Cache nicht um die Ausführungslogik der Methode kümmert. Er kann Folgendes feststellen: Wenn die Parameter für dieselbe Methode identisch sind, ist auch das Rückgabeergebnis dasselbe. Wenn die Parameter jedoch unterschiedlich sind, kann der Cache nur davon ausgehen, dass die Ergebnisse unterschiedlich sind. Wie viele Parameterkombinationen werden also für dieselbe Methode verwendet, um die Methode während der Ausführung Ihres Programms aufzurufen, und wie viele Cache-Schlüssel werden theoretisch generiert ( Die Parameter dieser Kombinationen beziehen sich natürlich auf den generierten Schlüssel). Werfen wir einen Blick auf einige Parameter von @Cacheable:
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Cacheable { @AliasFor("cacheNames") String[] value() default {}; @AliasFor("value") String[] cacheNames() default {}; String key() default ""; String keyGenerator() default ""; String cacheManager() default ""; String cacheResolver() default ""; String condition() default ""; String unless() default ""; boolean sync() default false; }
1. CacheNames & Value
Sie können einen von „Value“ oder „CacheNames“ verwenden, um den Cache-Namen anzugeben kann durch @Cacheable erreicht werden. Dies ist das einfachste Anwendungsbeispiel von @Cacheable: @Override
@Cacheable("menu")
public Menu findById(String id) {
Menu menu = this.getById(id);
if (menu != null){
System.out.println("menu.name = " + menu.getName());
}
return menu;
}
2. Verknüpfen Sie mehrere Cache-Namen
- Tatsächlich unterstützt @Cacheable laut offizieller Dokumentation dieselbe Methode zum Verknüpfen mehrerer Caches. In diesem Fall wird vor der Ausführung der Methode jeder dieser zugehörigen Caches überprüft, und solange
3.1 KeyGenerator generiert automatisch
Wenn wir @Cacheable deklarieren, ohne den Schlüsselparameter anzugeben, verwenden alle Schlüssel unter dem Cache-Namen automatisch KeyGenerator basierend auf Parametern generiert. Spring verfügt über einen Standard-SimpleKeyGenerator, der standardmäßig in die automatisierte Konfiguration von Spring Boot eingefügt wird. Die Generierungsregeln lauten wie folgt: #🎜🎜##🎜🎜##🎜🎜##🎜🎜#Wenn die Cache-Methode keine Parameter hat, wird SimpleKey.EMPTY zurückgegeben;#🎜🎜##🎜🎜##🎜🎜## 🎜🎜#Wenn die Cache-Methode einen Parameter hat und eine Instanz des Parameters zurückgibt; #🎜🎜##🎜🎜##🎜🎜##🎜🎜#Wenn die Cache-Methode mehrere Parameter hat, wird ein SimpleKey zurückgegeben, der alle Parameter enthält; #🎜🎜## 🎜🎜##🎜🎜##🎜🎜#Der Standardschlüsselgenerator erfordert Argumente mit gültigen Implementierungen der Methoden hashCode() und equal(). Alternativ können Sie den keyGenerator anpassen und über ihn festlegen. Ich werde hier keine detaillierte Einführung in KeyGenerator geben. Wenn Sie interessiert sind, können Sie sich den Quellcode ansehen. Tatsächlich verwendet er HashCode, um Additions- und Multiplikationsoperationen durchzuführen. Ähnlich wie Hash-Berechnungen für String und ArrayList. #🎜🎜##🎜🎜##🎜🎜#3.2 Schlüssel explizit angeben#🎜🎜##🎜🎜#相较于使用 KeyGenerator 生成,spring 官方更推荐显式指定 key 的方式,即指定 @Cacheable 的 key 参数。
即便是显式指定,但是 key 的值还是需要根据参数的不同来生成,那么如何实现动态拼接呢?SpEL(Spring Expression Language,Spring 表达式语言) 能做到这一点。下面是一些使用 SpEL 生成 key 的例子。
@Override @Cacheable(value = {"menuById"}, key = "#id") public Menu findById(String id) { Menu menu = this.getById(id); if (menu != null){ System.out.println("menu.name = " + menu.getName()); } return menu; } @Override @Cacheable(value = {"menuById"}, key = "'id-' + #menu.id") public Menu findById(Menu menu) { return menu; } @Override @Cacheable(value = {"menuById"}, key = "'hash' + #menu.hashCode()") public Menu findByHash(Menu menu) { return menu; }
官方说 key 和 keyGenerator 参数是互斥的,同时指定两个会导致异常。
4. cacheManager & cacheResolver
缓存管理器CacheManager用于管理(寻找)某种缓存。通常来讲,缓存管理器是与缓存组件类型相关联的。我们知道,spring 缓存抽象的目的是为使用不同缓存组件类型提供统一的访问接口,以向开发者屏蔽各种缓存组件的差异性。那么 CacheManager 就是承担了这种屏蔽的功能。spring 为其支持的每一种缓存的组件类型提供了一个默认的 manager,如:RedisCacheManager 管理 redis 相关的缓存的检索、EhCacheManager 管理 ehCache 相关的缓等。
CacheResolver,缓存解析器是用来管理缓存管理器的,CacheResolver 保持一个 cacheManager 的引用,并通过它来检索缓存。CacheResolver 与 CacheManager 的关系有点类似于 KeyGenerator 跟 key。spring 默认提供了一个 SimpleCacheResolver,开发者可以自定义并通过 @Bean 来注入自定义的解析器,以实现更灵活的检索。
大多数情况下,我们的系统只会配置一种缓存,所以我们并不需要显式指定 cacheManager 或者 cacheResolver。Spring允许我们在系统中配置多个缓存组件,这时我们需要进行明确的指定。指定的方式是使用 @Cacheable 的 cacheManager 或者 cacheResolver 参数。
按照官方文档,cacheManager 和 cacheResolver 是互斥参数,同时指定两个可能会导致异常。
5. sync
是否同步,true/false。在一个多线程的环境中,某些操作可能被相同的参数并发地调用,这样同一个 value 值可能被多次计算(或多次访问 db),这样就达不到缓存的目的。针对这些可能高并发的操作,我们可以使用 sync 参数来告诉底层的缓存提供者将缓存的入口锁住,这样就只能有一个线程计算操作的结果值,而其它线程需要等待,这样就避免了 n-1 次数据库访问。
sync = true 可以有效的避免缓存击穿的问题。
6. condition
调用前判断,缓存的条件。有时候,我们可能并不想对一个方法的所有调用情况进行缓存,我们可能想要根据调用方法时候的某些参数值,来确定是否需要将结果进行缓存或者从缓存中取结果。例如,当我查询用户时按年龄分组,我只需缓存那些年龄大于 35 的结果。那么 condition 能实现这种效果。
SpEL 支持的表达式可以作为 condition 的值,结果为 true 或 false。如果表达式结果为 true,则调用方法时会执行正常的缓存逻辑(查缓存-有就返回-没有就执行方法-方法返回不空就添加缓存);否则,调用方法时就好像该方法没有声明缓存一样(即无论传入了什么参数或者缓存中有些什么值,都会执行方法,并且结果不放入缓存)。下面举个例子:
我们看一下数据库,以这两条数据为例:
我们首先定义一个带条件的缓存方法:
@Override @Cacheable(value = {"menuById"}, key = "#id", condition = "#conditionValue > 1") public Menu findById(String id, Integer conditionValue) { Menu menu = this.getById(id); if (menu != null){ System.out.println("menu.name = " + menu.getName()); } return menu; }
然后分两种情况调用(为了直观可见,直接将 id 写在代码中):
@GetMapping("/findById/{id}") public Menu findById(@PathVariable("id")String id){ Menu menu0 = menuService.findById("fe278df654adf23cf6687f64d1549c0a", 0); Menu menu2 = menuService.findById("fb6106721f289ebf0969565fa8361c75", 2); return menu0; }
虽然两次请求都调用了方法,但只有第二次请求缓存了"微服务测试2"。只有在满足条件 condition 的情况下才会进行调用,这样才能将结果缓存。接下来我们再请求一遍,看下结果和打印:
可以看到,“微服务测试2”由于已经有了缓存,所以没有再执行方法体。而“微服务测试0”又一次执行了。
7. unless
执行后判断,不缓存的条件。SpEL 可以支持表达式结果为 true 或 false,用于 unless。当结果为 true 时,不缓存。举个例子:
我们先清除 redis 中的数据。然后看看 mysql 中的数据:
然后编写一个缓存方法(在该方法中,result代表方法的返回值。关于):
@Override @Cacheable(value = {"menuById"}, key = "#id", unless = "#result.type == 'folder'") public Menu findById(String id) { Menu menu = this.getById(id); if (menu != null){ System.out.println("menu.name = " + menu.getName()); } return menu; }
然后调用该方法:
@GetMapping("/findById/{id}") public Menu findById(@PathVariable("id")String id){ Menu menu0 = menuService.findById("fe278df654adf23cf6687f64d1549c0a"); Menu menu2 = menuService.findById("fb6106721f289ebf0969565fa8361c75"); return menu0; }
可以看到,两次都执行了方法体(其实,unless 条件就是在方法执行完毕后调用,所以它不会影响方法的执行),但是结果只有 menu.type = ‘page’ 的缓存了,说明 unless 参数生效了。
8. condition VS unless ?
既然 condition 和 unless 都能决定是否进行缓存,那么同时指定这两个参数并且结果相冲突的时候,会怎么样呢?我们来试一试。
首先清除 redis 数据,然后在缓存方法上加上 condition=“true”,如:
@Override @Cacheable(value = {"menuById"}, key = "#id", condition = "true", unless = "#result.type == 'folder'") public Menu findById(String id) { Menu menu = this.getById(id); if (menu != null){ System.out.println("menu.name = " + menu.getName()); } return menu; }
其它代码不变,我们来看一下缓存结果和打印:
可以看到,虽然两次调用都执行了,但是,type=‘folder’ 的还是被排除了。在这种情况下,unless 的优先级高于 condition。接着,我们将condition设为“false”,再进行尝试,结果是:
可以看到,两次调用的结果都没有缓存。在这种情况下,优先使用condition而不是unless。总结起来就是:
Das obige ist der detaillierte Inhalt vonWie SpringBoot @Cacheable zum Zwischenspeichern und Abrufen von Werten verwendet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Einführung in Jasypt Jasypt ist eine Java-Bibliothek, die es einem Entwickler ermöglicht, seinem Projekt mit minimalem Aufwand grundlegende Verschlüsselungsfunktionen hinzuzufügen und kein tiefes Verständnis der Funktionsweise der Verschlüsselung erfordert. standardbasierte Verschlüsselungstechnologie. Passwörter, Text, Zahlen, Binärdateien verschlüsseln ... Geeignet für die Integration in Spring-basierte Anwendungen, offene API, zur Verwendung mit jedem JCE-Anbieter ... Fügen Sie die folgende Abhängigkeit hinzu: com.github.ulisesbocchiojasypt-spring-boot-starter2 Die Vorteile von Jasypt schützen unsere Systemsicherheit. Selbst wenn der Code durchgesickert ist, kann die Datenquelle garantiert werden.

Nutzungsszenario 1. Die Bestellung wurde erfolgreich aufgegeben, die Zahlung erfolgte jedoch nicht innerhalb von 30 Minuten. Die Zahlung ist abgelaufen und die Bestellung wurde automatisch storniert. 2. Die Bestellung wurde unterzeichnet und es wurde 7 Tage lang keine Bewertung durchgeführt. Wenn die Bestellung abläuft und nicht ausgewertet wird, wird die Bestellung standardmäßig positiv bewertet. Wenn der Händler die Bestellung innerhalb von 5 Minuten nicht erhält, wird die Bestellung abgebrochen Es wird eine SMS-Erinnerung gesendet ... Für Szenarien mit langen Verzögerungen und geringer Echtzeitleistung können wir die Aufgabenplanung verwenden, um eine regelmäßige Abfrageverarbeitung durchzuführen. Zum Beispiel: xxl-job Heute werden wir auswählen

1. Redis implementiert das Prinzip der verteilten Sperren und warum verteilte Sperren erforderlich sind. Bevor über verteilte Sperren gesprochen wird, muss erläutert werden, warum verteilte Sperren erforderlich sind. Das Gegenteil von verteilten Sperren sind eigenständige Sperren. Wenn wir Multithread-Programme schreiben, vermeiden wir Datenprobleme, die durch den gleichzeitigen Betrieb einer gemeinsam genutzten Variablen verursacht werden. Normalerweise verwenden wir eine Sperre, um die Richtigkeit der gemeinsam genutzten Variablen sicherzustellen Die gemeinsam genutzten Variablen liegen im gleichen Prozess. Wenn es mehrere Prozesse gibt, die gleichzeitig eine gemeinsam genutzte Ressource betreiben müssen, wie können sie sich dann gegenseitig ausschließen? Heutige Geschäftsanwendungen sind in der Regel Microservice-Architekturen, was auch bedeutet, dass eine Anwendung mehrere Prozesse bereitstellen muss. Wenn mehrere Prozesse dieselbe Datensatzzeile in MySQL ändern müssen, ist eine Verteilung erforderlich, um fehlerhafte Daten zu vermeiden wird zu diesem Zeitpunkt eingeführt. Der Stil ist gesperrt. Punkte erreichen wollen

Springboot liest die Datei, kann aber nach dem Packen in ein JAR-Paket nicht auf die neueste Entwicklung zugreifen. Es gibt eine Situation, in der Springboot die Datei nach dem Packen in ein JAR-Paket nicht lesen kann ist ungültig und kann nur über den Stream gelesen werden. Die Datei befindet sich unter resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

Wenn Springboot + Mybatis-plus keine SQL-Anweisungen zum Hinzufügen mehrerer Tabellen verwendet, werden die Probleme, auf die ich gestoßen bin, durch die Simulation des Denkens in der Testumgebung zerlegt: Erstellen Sie ein BrandDTO-Objekt mit Parametern, um die Übergabe von Parametern an den Hintergrund zu simulieren dass es äußerst schwierig ist, Multi-Table-Operationen in Mybatis-plus durchzuführen. Wenn Sie keine Tools wie Mybatis-plus-join verwenden, können Sie nur die entsprechende Mapper.xml-Datei konfigurieren und die stinkende und lange ResultMap konfigurieren Schreiben Sie die entsprechende SQL-Anweisung. Obwohl diese Methode umständlich erscheint, ist sie äußerst flexibel und ermöglicht es uns

SpringBoot und SpringMVC sind beide häufig verwendete Frameworks in der Java-Entwicklung, es gibt jedoch einige offensichtliche Unterschiede zwischen ihnen. In diesem Artikel werden die Funktionen und Verwendungsmöglichkeiten dieser beiden Frameworks untersucht und ihre Unterschiede verglichen. Lassen Sie uns zunächst etwas über SpringBoot lernen. SpringBoot wurde vom Pivotal-Team entwickelt, um die Erstellung und Bereitstellung von Anwendungen auf Basis des Spring-Frameworks zu vereinfachen. Es bietet eine schnelle und einfache Möglichkeit, eigenständige, ausführbare Dateien zu erstellen

1. Passen Sie den RedisTemplate1.1-Standard-Serialisierungsmechanismus an. Die API-basierte Redis-Cache-Implementierung verwendet die RedisTemplate-Vorlage für Daten-Caching-Vorgänge. Öffnen Sie hier die RedisTemplate-Klasse und zeigen Sie die Quellcodeinformationen der Klasse publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations an. Schlüssel deklarieren, verschiedene Serialisierungsmethoden des Werts, der Anfangswert ist leer @NullableprivateRedisSe

In Projekten werden häufig einige Konfigurationsinformationen benötigt. Diese Informationen können in der Testumgebung und in der Produktionsumgebung unterschiedliche Konfigurationen haben und müssen möglicherweise später basierend auf den tatsächlichen Geschäftsbedingungen geändert werden. Wir können diese Konfigurationen nicht fest im Code codieren. Am besten schreiben Sie sie in die Konfigurationsdatei. Sie können diese Informationen beispielsweise in die Datei application.yml schreiben. Wie erhält oder verwendet man diese Adresse im Code? Es gibt 2 Methoden. Methode 1: Wir können den Wert, der dem Schlüssel in der Konfigurationsdatei (application.yml) entspricht, über den mit @Value versehenen Wert erhalten. Diese Methode eignet sich für Situationen, in denen es relativ wenige Mikrodienste gibt: Tatsächlich Projekte, wenn das Geschäft kompliziert ist, Logik
