SpringBoot実戦(十一)|統合データキャッシュCache


微信公衆番号:優秀な廃人
問題やアドバイスがあれば、楽屋に伝言を残してください.私はできるだけあなたの問題を解決します.
前言
さて、今日はSpringBootのデータキャッシュについてご紹介します.開発したことのあるプログラムのボトルネックはデータベースにあることはよく知られています.メモリの速度はハードディスクよりも大幅に速いことも知っています.同じデータを繰り返し取得する必要がある場合、データベースやリモートサービスを何度も要求し、データベースのクエリーや遠隔メソッドの呼び出しに多くの時間を費やし、性能の悪化を招きます.これはデータキャッシュが解決しなければならない問題です.
Springのキャッシュサポート
Springはorgを定義する.springframework.cache.CacheManagerとorg.springframework.cache.Cacheインタフェースは、異なるキャッシュ技術を統合するために使用されます.ここで、CacheManagerはSpringが提供する各種キャッシュ技術の抽象インタフェースであり、Cacheインタフェースはキャッシュを含む各種操作である(増加、削除、キャッシュの取得、一般的にこのインタフェースと直接は付き合わない).
1、SpringがサポートするCacheManager
異なるキャッシュ技術に対して異なるCacheManagerを実現し、Springは以下の表に示すCacheManagerを定義した.
CacheManager
説明
SimpleCacheManager
簡単なCollectionを使用してキャッシュを格納し、主にテストに使用します.
ConcurrentMapCacheManager
ConcurrentMapを使用してキャッシュを格納
NoOpCacheManager
用途のみをテストし、実際にデータをキャッシュしません.
EhCacheCacheManager
キャッシュ・テクノロジーとしてEhCacheを使用
GuavaCacheManager
Google GuavaのGuavaCacheをキャッシュ技術として使用
HazelcastCacheManager
キャッシュ・テクノロジーとしてHazelcastを使用
JCacheCacheManager
JCache(JSR-107)標準の実現をキャッシュ技術としてサポートし、例えばApacheCommonsJCS
RedisCacheManager
Redisをキャッシュ・テクノロジーとして使用
以上のいずれかのインプリメンテーションのCacheManagerを使用する場合は、インプリメンテーションのCacheManagerのBeanを登録する必要があります.
@Bean
public EhCacheCacheManager cacheManager(CacheManager 
 ehCacheCacheManager){
    return new  EhCacheCacheManager(ehCacheCacheManager);
}

各キャッシュ・テクノロジーには追加の構成がたくさんありますが、cacheManagerの構成は欠かせません.
2、宣言式キャッシュ注記
Springでは、キャッシュ・ルールを宣言するために4つの注釈が用意されています(注釈式のAOPを使用する例もあります).4つの注釈は以下のように表されます.
注釈
説明する
@Cacheable
メソッドが実行される前にSpringはキャッシュにデータがあるかどうかを確認し、ある場合はキャッシュデータを直接返します.データがない場合、呼び出しメソッドはメソッドの戻り値をキャッシュに格納します.
@CachePut
いずれにしても、メソッドの戻り値はキャッシュに格納されます.
@CacheEvict
1つ以上のデータをキャッシュから削除
@Caching
@Caching注記で複数の注記ポリシーを1つの方法で組み合わせることができます.
@Cacheable、@CachePut、@CacheEveictにはvalueプロパティがあり、使用するキャッシュ名を指定します.keyプロパティは、データがキャッシュに格納されるキーを指定します.
3、宣言式キャッシュサポートを開く
宣言キャッシュを開くのは簡単です.構成クラスで@EnableCaching注記を使用するだけでいいです.たとえば、次のようにします.
@Configuration
@EnableCaching
public class AppConfig{

}

SpringBootのサポート
Springでキャッシュ・テクノロジーを使用する鍵はCacheManagerの構成ですが、SpringBootでは複数のCacheManagerの実装を構成しています.
自動構成はorgにあります.springframework.boot.autoconfigure.Cacheパッケージにあります.
コンフィギュレーションを行わない場合、デフォルトではSimpleCacheConfiguration、すなわちConcurrentMapCacheManagerが使用されます.SpringBootは、キャッシュを構成するために以前の接頭辞をサポートします.例:
spring.cache.type= #    generic、ehcache、hazelcast、infinispan、jcache、redis、guava、simple、none
spring.cache.cache-names= #             
spring.cache.ehcache.config= # ehcache        
spring.cache.hazelcast.config= # hazelcast       
spring.cache.infinispan.config= # infinispan       
spring.cache.jcache.config= # jcache       
spring.cache.jcache.provider= #     jcache          ,   jcache   
#   。。。

SpringBoot環境では、キャッシュ・テクノロジーを使用するには、プロジェクトに関連するキャッシュ・テクノロジーの依存パッケージをインポートし、構成クラスで@EnableCachingを使用してキャッシュ・サポートを開くだけです.
コード実装
ここでは、SpringBootのデフォルトのConcurrentMapCacheManagerをキャッシュ技術として、@Cacheable、@CachePut、@CacheEveictを実証します.
1、準備
  • IDEA
  • JDK 1.8
  • SpringBoot 2.1.3

  • 2、Pom.xmlファイル依存
    
    
        4.0.0
        
            org.springframework.boot
            spring-boot-starter-parent
            2.1.3.RELEASE
             
        
        com.nasus
        cache
        0.0.1-SNAPSHOT
        cache
        cache Demo project for Spring Boot
    
        
            1.8
        
    
        
            
            
                org.springframework.boot
                spring-boot-starter-cache
            
            
            
                org.springframework.boot
                spring-boot-starter-data-jpa
            
            
            
                org.springframework.boot
                spring-boot-starter-web
            
            
            
                mysql
                mysql-connector-java
                runtime
            
            
            
                org.projectlombok
                lombok
                true
            
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
        
    
        
            
                
                    org.springframework.boot
                    spring-boot-maven-plugin
                
            
        
    
    

    注釈ははっきりしていて、余計なことを言う必要はありません.グーグルだけではありません.
    3、Application.yamlファイル構成
    spring:
      #      
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=true
        username: root
        password: 123456
      # jpa   
      jpa:
        hibernate:
          ddl-auto: update   # ddl-auto:    create          
        show-sql: true

    4、エンティティークラス
    package com.nasus.cache.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @Entity
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student {
    
        @Id
        @GeneratedValue
        private Integer id;
    
        private String name;
    
        private Integer age;
    
    }

    5、dao層
    package com.nasus.cache.repository;
    
    import com.nasus.cache.entity.Student;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface StudentRepository extends JpaRepository {
    }

    6、サービス層
    package com.nasus.cache.service;
    
    import com.nasus.cache.entity.Student;
    
    public interface StudentService {
    
        public Student saveStudent(Student student);
    
        public void deleteStudentById(Integer id);
    
        public Student findStudentById(Integer id);
    
    }

    実装クラス:
    package com.nasus.cache.service.impl;
    
    import com.nasus.cache.entity.Student;
    import com.nasus.cache.repository.StudentRepository;
    import com.nasus.cache.service.StudentService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    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;
    
    @Service
    public class StudentServiceImpl implements StudentService {
    
        //    slf4j       
        private static final Logger LOGGER = LoggerFactory.getLogger(StudentServiceImpl.class);
    
        @Autowired
        private StudentRepository studentRepository;
    
        @Override
        @CachePut(value = "student",key = "#student.id")
        // @CachePut               ,        student     key   student   id
        public Student saveStudent(Student student) {
            Student s = studentRepository.save(student);
            LOGGER.info(" id、key  {}       ", s.getId());
            return s;
        }
    
        @Override
        @CacheEvict(value = "student")
        // @CacheEvict     student     key   id    
        public void deleteStudentById(Integer id) {
            LOGGER.info("   id、key  {}     ", id);
            //studentRepository.deleteById(id);
        }
    
        @Override
        @Cacheable(value = "student",key = "#id")
        // @Cacheable    key   id        student  
        public Student findStudentById(Integer id) {
            Student s = studentRepository.findById(id).get();
            LOGGER.info(" id、key  {}       ", id);
            return  s;
        }
    }

    コードの説明は注釈を見て、とても詳しいです.
    7、コントロール層
    package com.nasus.cache.controller;
    
    import com.nasus.cache.entity.Student;
    import com.nasus.cache.service.StudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.Mapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/student")
    public class StudentController {
    
        @Autowired
        private StudentService studentService;
    
        @PostMapping("/put")
        public Student saveStudent(@RequestBody Student student){
            return studentService.saveStudent(student);
        }
    
        @DeleteMapping("/evit/{id}")
        public void deleteStudentById(@PathVariable("id") Integer id){
            studentService.deleteStudentById(id);
        }
    
        @GetMapping("/able/{id}")
        public Student findStudentById(@PathVariable("id") Integer id){
            return studentService.findStudentById(id);
        }
    
    }

    8、アプリケーションオープンキャッシュ機能
    package com.nasus.cache;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    @EnableCaching //       
    @SpringBootApplication
    public class CacheApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(CacheApplication.class, args);
        }
    }

    テスト
    テストの前に、データベースの現在のデータを見てみましょう.次のようにします.
    1、テスト@Cacheable
    アクセスhttp://localhost:8080/student/able/2コンソールからSQLクエリー文と指定したログが印刷されます.今回のプログラムがデータベースを直接クエリーした結果であることを示します.
    2019-02-21 22:54:54.651  INFO 1564 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 11 ms
    Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
    2019-02-21 22:54:59.725  INFO 1564 --- [nio-8080-exec-1] c.n.c.service.impl.StudentServiceImpl    :  id、key  2       

    postmanの最初のテスト結果:
    再アクセスhttp://localhost:8080/student/able/2結果は下図のようです.しかし、コンソールにはSQL文の印刷もなく、id、keyが2のデータをキャッシュする言葉の出力もありません.
    説明@Cacheableは確かにデータキャッシュを行いましたが、2回目のテスト結果はデータキャッシュから取得され、直接データベースを調べませんでした.
    2、テスト@CachePut
    次の図、postmanアクセスhttp://localhost:8080/student/putデータの挿入:
    次に、SQL Insert挿入文と指定したログをコンソールで印刷します.説明プログラムがキャッシュされています.
    Hibernate: insert into student (age, name, id) values (?, ?, ?)
    2019-02-21 23:12:03.688  INFO 1564 --- [nio-8080-exec-8] c.n.c.service.impl.StudentServiceImpl    :  id、key  4       

    データが返す結果を挿入:
    データベースの結果:
    アクセスhttp://localhost:8080/student/able/4Postmanの結果は下図のようです.コンソールに出力がなく、@CachePutがキャッシュされていることを確認しました.下図のデータはキャッシュから取得されています.
    3、テスト@CacheEveict
    postmanアクセスhttp://localhost:8080/student/able/3id=3のデータをキャッシュします.
    postman再アクセスhttp://localhost:8080/student/able/3キャッシュからデータが取得されたことを確認します.
    postmanアクセスhttp://localhost:8080/student/evit/3
    キャッシュからkeyが3のキャッシュデータを削除するには、次の手順に従います.
    Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
    2019-02-21 23:26:08.516  INFO 8612 --- [nio-8080-exec-2] c.n.c.service.impl.StudentServiceImpl    :  id、key  3       
    2019-02-21 23:27:01.508  INFO 8612 --- [nio-8080-exec-4] c.n.c.service.impl.StudentServiceImpl    :    id、key  3     

    再postmanアクセスhttp://localhost:8080/student/able/3バックグラウンドを観察し、データキャッシュを再作成します.
    Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
    2019-02-21 23:27:12.320  INFO 8612 --- [nio-8080-exec-5] c.n.c.service.impl.StudentServiceImpl    :  id、key  3       

    この一連のテストプロセスにより、@CacheEveictがデータキャッシュを削除したことが証明されました.
    ソースのダウンロード
    https://github.com/turoDog/Demo/tree/master/springboot_cache_demo
    キャッシュ・テクノロジーの切り替え
    スイッチングキャッシュ技術はpomファイルに関連する依存パケット構成を加える以外は,上記のコードプレゼンテーションと同様に使用する.
    1、EhCacheを切り替えてpomにEncache依存を追加する:
    
    
         net.sf.ehcache
         ehcache
    

    Ehcacheに必要なプロファイルehcache.xmlはクラスパス(resourceディレクトリ)の下に置くだけで、SpringBootは次のように自動的にスキャンされます.
    
    
        
    

    SpringBootでは、EhcacheManagerのBeanが自動的に構成されます.
    2、Guavaの切り替え
    pomにGuava依存を追加するだけです.
    
    
         com.google.guava
         guava
         18.0
    

    SpringBootではGuavaCacheManagerのBeanが自動的に構成されます.
    3、RedisCacheの切り替え
    Guavaと同様にpomに依存を加えるだけでよい:
    
             
        org.springframework.boot
        spring-boot-starter-redis
    

    SpringBootでは、RedisCacheManagerおよびRedisTemplateのBeanが自動的に構成されます.
    また、他のキャッシュテクノロジーを切り替える方法も同様です.ここでは余計なことは言わない.
    後語
    SpringBootデータキャッシュのチュートリアルです.
    もし本文があなたに少しでも役に立つなら、少し手伝ってください.
    あなたの美しさは私が書くことを堅持する原動力です.
    また、フォローアップ後に1024を送信すると無料学習資料を受け取ることができる.資料の内容の詳細はこの古い文を見てください:Python、C++、Java、Linux、Go、フロントエンド、アルゴリズムの資料の共有