spring boot 集成EHCache

本章知识点:Spring Data JPA,Spring Boot 使用Mysql,Spring MVC,EHCache,Spring Cache等(其中@Cacheable请看上一节的理论知识),具体分如下几个步骤:

步骤 描述
1 新建Maven Java Project
2 在pom.xml中加入依赖包
3 编写Spring Boot启动类;
4 配置application.properties;
5 编写缓存配置类以及ehcache.xml配置文件
6 编写DemoInfo实体类进行测试;
7 编写持久类DemoInfoRepository;
8 编写处理类DemoInfoService;
9 编写DemoInfoController测试类;运行测试

接下来是具体实现

1)新建Maven Java Project

 新建一个工程名为spring-boot-ehcache的maven java project。

(2)在pom.xml中加入依赖包

  在pom.xml文件中加入相应的依赖包,Spring Boot父节点依赖包;spring boot web支持;缓存依赖spring-context-support;集成ehcache需要的依赖;JPA操作数据库;mysql 数据库驱动,具体pom.xml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
< project  xmlns = "http://maven.apache.org/POM/4.0.0"  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
     < modelVersion >4.0.0 modelVersion >
  
     < groupId >com.kfit groupId >
     < artifactId >spring-boot-ehcache artifactId >
     < version >0.0.1-SNAPSHOT version >
     < packaging >jar packaging >
  
     < name >spring-boot-ehcache name >
     < url >http://maven.apache.org url >
  
     < properties >
        < project.build.sourceEncoding >UTF-8 project.build.sourceEncoding >
  
       
        < java.version >1.8 java.version >
     properties >
  
  
    
     < parent >
        < groupId >org.springframework.boot groupId >
        < artifactId >spring-boot-starter-parent artifactId >
        < version >1.3.3.RELEASE version >
     parent >
  
     < dependencies >
       
        < dependency >
            < groupId >junit groupId >
            < artifactId >junit artifactId >
            < scope >test scope >
        dependency >
  
       
        < dependency >
            < groupId >org.springframework.boot groupId >
            < artifactId >spring-boot-starter-web artifactId >
        dependency >
       
       
        < dependency >
           < groupId >org.springframework groupId >
           < artifactId >spring-context-support artifactId >
         dependency >
  
       
        < dependency >
            < groupId >net.sf.ehcache groupId >
            < artifactId >ehcache artifactId >
        dependency >
       
       
        < dependency >
           < groupId >org.springframework.boot groupId >
           < artifactId >spring-boot-starter-data-jpa artifactId >
         dependency >
       
       
        < dependency >
           < groupId >mysql groupId >
           < artifactId >mysql-connector-java artifactId >
         dependency >
        
        
        < dependency >
             < groupId >org.springframework.boot groupId >
             < artifactId >spring-boot-starter-test artifactId >
             < scope >test scope >
         dependency >
     dependencies >
project >

3)编写Spring Boot启动类(com.kfit.App.java);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package  com.kfit;
  
import  org.springframework.boot.SpringApplication;
import  org.springframework.boot.autoconfigure.SpringBootApplication;
  
/**
  *
  *
  * @SpringBootApplication申明让spring boot自动给程序进行必要的配置,
  *
@SpringBootApplication
等待于:
@Configuration
@EnableAutoConfiguration
@ComponentScan
  *
 
  * @version v.0.1
  */
@SpringBootApplication
public  class  App {
     public  static  void  main(String[] args) {
        SpringApplication.run(App. class , args);
     }
}

(4)配置application.properties;

在application.properties中主要配置数据库连接和JPA的基本配置,具体如下:

Src/main/resouces/application.properties:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
########################################################
###datasource ,mysql数据库连接配置
########################################################
spring.datasource.url = jdbc:mysql: //localhost:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active= 20
spring.datasource.max-idle= 8
spring.datasource.min-idle= 8
spring.datasource.initial-size= 10
  
  
  
########################################################
### Java Persistence Api ,JPA自动建表操作配置
########################################################
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log  for  each sql query
spring.jpa.show-sql =  true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

5)编写缓存配置类以及ehcache.xml配置文件:

 这个类主要是注册缓存管理对象EhCacheCacheManager、缓存工厂对象EhCacheManagerFactoryBean,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package  com.kfit.config;
  
import  org.springframework.cache.annotation.EnableCaching;
import  org.springframework.cache.ehcache.EhCacheCacheManager;
import  org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import  org.springframework.context.annotation.Bean;
import  org.springframework.context.annotation.Configuration;
import  org.springframework.core.io.ClassPathResource;
  
/**
  * 缓存配置.
 
  * @version v.0.1
  */
@Configuration
@EnableCaching //标注启动缓存.
public  class  CacheConfiguration {
    
     /**
      *  ehcache 主要的管理器
      * @param bean
      * @return
      */
     @Bean
     public  EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean){
        System.out.println( "CacheConfiguration.ehCacheCacheManager()" );
        return  new  EhCacheCacheManager(bean.getObject());
     }
    
     /*
        * 据shared与否的设置,
        * Spring分别通过CacheManager.create()
        * 或new CacheManager()方式来创建一个ehcache基地.
        *
        * 也说是说通过这个来设置cache的基地是这里的Spring独用,还是跟别的(如hibernate的Ehcache共享)
        *
        */
       @Bean
       public  EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
         System.out.println( "CacheConfiguration.ehCacheManagerFactoryBean()" );
         EhCacheManagerFactoryBean cacheManagerFactoryBean =  new  EhCacheManagerFactoryBean ();
         cacheManagerFactoryBean.setConfigLocation ( new  ClassPathResource( "conf/ehcache.xml" ));
         cacheManagerFactoryBean.setShared( true );
         return  cacheManagerFactoryBean;
       }
    
}

在src/main/resouces/conf下编写ehcache.xml配置文件,当然这个文件你可以放在其它目录下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
xml  version = "1.0"  encoding = "UTF-8" ?>
< ehcache  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation = "http://ehcache.org/ehcache.xsd"
     updateCheck = "false" >
    
    
    
     < diskStore  path = "java.io.tmpdir/Tmp_EhCache"  />
    
    
      
     
     < defaultCache
        eternal = "false"
        maxElementsInMemory = "1000"
        overflowToDisk = "false"
        diskPersistent = "false"
        timeToIdleSeconds = "0"
        timeToLiveSeconds = "600"
        memoryStoreEvictionPolicy = "LRU"  />
  
     < cache
        name = "demo"  
        eternal = "false"
        maxElementsInMemory = "100"
        overflowToDisk = "false"
        diskPersistent = "false"
        timeToIdleSeconds = "0"
        timeToLiveSeconds = "300"
        memoryStoreEvictionPolicy = "LRU"  />
       
ehcache >

(6)编写DemoInfo实体类进行测试;

在com.kfit.bean下编写DemoInfo实体类进行缓存测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package  com.kfit.bean;
  
import  javax.persistence.Entity;
import  javax.persistence.GeneratedValue;
import  javax.persistence.Id;
  
/**
  * 测试实体类.
  
  * @version v.0.1
  */
@Entity
public  class  DemoInfo {
     @Id  @GeneratedValue
     private  longid; //主键.
     private  String name; //名称;
     private  String pwd; //密码;
     private  intstate;
     public  long  getId() {
        returnid;
     }
     public  void  setId(longid) {
        this .id = id;
     }
     public  String getName() {
        returnname;
     }
     publicvoid setName(String name) {
        this .name = name;
     }
     public  String getPwd() {
        returnpwd;
     }
     public  void  setPwd(String pwd) {
        this .pwd = pwd;
     }
     public  int  getState() {
        returnstate;
     }
     public  void  setState(intstate) {
        this .state = state;
     }
     @Override
     public  String toString() {
        return  "DemoInfo [id="  + id +  ", name="  + name +  ", pwd="  + pwd +  ", state="  + state +  "]" ;
     }
}

(7)编写持久类DemoInfoRepository;

编写持久类DemoInfoRepository:

com.kfit.repository.DemoInfoRepository:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package  com.kfit.repository;
  
import  org.springframework.data.repository.CrudRepository;
  
import  com.kfit.bean.DemoInfo;
  
/**
  * 操作数据库.
 
  * @version v.0.1
  */
public  interface  DemoInfoRepository  extends  CrudRepository{
  
}

(8)编写处理类DemoInfoService;

编写增删改查的方法,在这几个方法中都使用注解缓存,进行缓存的创建以及删除,修改等操作:

com.kfit.service.DemoInfoService:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package  com.kfit.service;
  
import  com.kfit.bean.DemoInfo;
  
import  javassist.NotFoundException;
  
public  interface  DemoInfoService {
  
     void  delete(Long id);
  
     DemoInfo update(DemoInfo updated)  throws  NotFoundException;
  
     DemoInfo findById(Long id);
  
     DemoInfo save(DemoInfo demoInfo);
  
}

com.kfit.service.impl.DemoInfoServiceImpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package  com.kfit.service.impl;
  
import  javax.annotation.Resource;
  
import  org.springframework.cache.annotation.CacheEvict;
import  org.springframework.cache.annotation.CachePut;
import  org.springframework.cache.annotation.Cacheable;
import  org.springframework.stereotype.Service;
  
import  com.kfit.bean.DemoInfo;
import  com.kfit.repository.DemoInfoRepository;
import  com.kfit.service.DemoInfoService;
  
import  javassist.NotFoundException;
  
@Service
public  class  DemoInfoServiceImpl  implements  DemoInfoService {
    
     //这里的单引号不能少,否则会报错,被识别是一个对象;
     public  static  final  String CACHE_KEY =  "'demoInfo'" ;
   
      @Resource
      private  DemoInfoRepository demoInfoRepository;
    
     /**
      * value属性表示使用哪个缓存策略,缓存策略在ehcache.xml
     */
     public  static  final  String DEMO_CACHE_NAME =  "demo" ;
    
     /**
      * 保存数据.
      * @param demoInfo
      */
     @CacheEvict (value=DEMO_CACHE_NAME,key=CACHE_KEY)
     @Override
     public  DemoInfo save(DemoInfo demoInfo){
        return  demoInfoRepository.save(demoInfo);
     }
    
     /**
      * 查询数据.
      * @param id
      * @return
      */
     @Cacheable (value=DEMO_CACHE_NAME,key= "'demoInfo_'+#id" )
     @Override
     public  DemoInfo findById(Long id){
        System.err.println( "没有走缓存!" +id);
        return  demoInfoRepository.findOne(id);
     }
    
     /**
      * http://www.mincoder.com/article/2096.shtml:
      *
      * 修改数据.
      *
      * 在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
  
        @CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
      *
      * @param updated
      * @return
      *
      * @throws NotFoundException
      */
     @CachePut (value = DEMO_CACHE_NAME,key =  "'demoInfo_'+#updated.getId()" )
     //@CacheEvict(value = DEMO_CACHE_NAME,key = "'demoInfo_'+#updated.getId()")//这是清除缓存.
     @Override
     public  DemoInfo update(DemoInfo updated)  throws  NotFoundException{
        DemoInfo demoInfo = demoInfoRepository.findOne(updated.getId());
        if (demoInfo ==  null ){
            thrownew NotFoundException( "No find" );
        }
        demoInfo.setName(updated.getName());
        demoInfo.setPwd(updated.getPwd());
        return  demoInfo;
     }
    
    
     /**
      * 删除数据.
      * @param id
      */
     @CacheEvict (value = DEMO_CACHE_NAME,key =  "'demoInfo_'+#id" ) //这是清除缓存.
     @Override
     public  void  delete(Long id){
        demoInfoRepository.delete(id);
     }
       
    
}

(9)编写DemoInfoController测试类;

编写一个rest进行测试:

com.kfit.controller.DemoInfoController:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package  com.kfit.controller;
  
import  javax.annotation.Resource;
  
import  org.springframework.web.bind.annotation.RequestMapping;
import  org.springframework.web.bind.annotation.RestController;
  
import  com.kfit.bean.DemoInfo;
import  com.kfit.service.DemoInfoService;
  
import  javassist.NotFoundException;
  
@RestController
public  class  DemoInfoController {
  
     @Resource
     private  DemoInfoService demoInfoService;
    
     @RequestMapping ( "/test" )
     public  String test(){
       
        //存入两条数据.
         DemoInfo demoInfo =  new  DemoInfo();
         demoInfo.setName( "张三" );
         demoInfo.setPwd( "123456" );
         DemoInfo demoInfo2 = demoInfoService.save(demoInfo);
       
         //不走缓存.
         System.out.println(demoInfoService.findById(demoInfo2.getId()));
         //走缓存.
         System.out.println(demoInfoService.findById(demoInfo2.getId()));
        
        
         demoInfo =  new  DemoInfo();
         demoInfo.setName( "李四" );
         demoInfo.setPwd( "123456" );
         DemoInfo demoInfo3 = demoInfoService.save(demoInfo);
        
         //不走缓存.
         System.out.println(demoInfoService.findById(demoInfo3.getId()));
         //走缓存.
         System.out.println(demoInfoService.findById(demoInfo3.getId()));
        
         System.out.println( "============修改数据=====================" );
         //修改数据.
         DemoInfo updated =  new  DemoInfo();
         updated.setName( "李四-updated" );
         updated.setPwd( "123456" );
         updated.setId(demoInfo3.getId());
         try  {
            System.out.println(demoInfoService.update(updated));
        catch  (NotFoundException e) {
            e.printStackTrace();
        }
        
         //不走缓存.
         System.out.println(demoInfoService.findById(updated.getId()));
        
        return  "ok" ;
     }
    
    
}

(10)运行测试;

运行App.java进行测试,访问:http://127.0.0.1:8080/test 进行测试,主要是观察控制台的打印信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存! 52
DemoInfo [id= 52 , name=张三, pwd= 123456 , state= 0 ]
DemoInfo [id= 52 , name=张三, pwd= 123456 , state= 0 ]
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存! 53
DemoInfo [id= 53 , name=李四, pwd= 123456 , state= 0 ]
DemoInfo [id= 53 , name=李四, pwd= 123456 , state= 0 ]
============修改数据=====================
DemoInfo [id= 53 , name=李四-updated, pwd= 123456 , state= 0 ]
DemoInfo [id= 53 , name=李四-updated, pwd= 123456 , state= 0 ]
C:\Users\ADMINI~ 1 .ANG\AppData\Local\Temp\
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存! 54
DemoInfo [id= 54 , name=张三, pwd= 123456 , state= 0 ]
DemoInfo [id= 54 , name=张三, pwd= 123456 , state= 0 ]
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存! 55
DemoInfo [id= 55 , name=李四, pwd= 123456 , state= 0 ]
DemoInfo [id= 55 , name=李四, pwd= 123456 , state= 0 ]
============修改数据=====================
DemoInfo [id= 55 , name=李四-updated, pwd= 123456 , state= 0 ]
DemoInfo [id= 55 , name=李四-updated, pwd= 123456 , state= 0 ]

你可能感兴趣的:(Spring,Boot,spring,boot,集成EHCach)