springboot ehcache缓存使用及自定义缓存存取

添加依赖
首先在pom.xml添加必要依赖


        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-cacheartifactId>
        dependency>
        <dependency>
            <groupId>net.sf.ehcachegroupId>
            <artifactId>ehcacheartifactId>
        dependency>

添加依赖时会提示net.sf.ehcache已经集成在springboot里边,但是不加程序又提示找不到net.sf.ehcache.CacheManager的class文件。该问题需要朋友们解决一下。
开启缓存
在Spring Boot环境下,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在配置类上使用@EnableCaching开启缓存即可。
在启动类添加注解@EnableCaching

@SpringBootApplication
@EnableCaching
public class MyTestApplication  {
    private static Logger log=LoggerFactory.getLogger(MyTestApplication .class);
    public static void main(String[] args) {
        SpringApplication.run(MyTestApplication .class, args);
        log.info("服务启动成功");
    }
}

新建数据库表

CREATE TABLE `paraconfig` (
  `paraId` int(11) NOT NULL AUTO_INCREMENT COMMENT '参数id',
  `paraName` varchar(20) NOT NULL COMMENT '参数名称',
  `paraCode` varchar(50) NOT NULL COMMENT '参数值',
  `paraDesc` varchar(100) DEFAULT NULL COMMENT '参数描述',
  `status` enum('有效','无效') NOT NULL COMMENT '参数状态',
  PRIMARY KEY (`paraId`),
  UNIQUE KEY `paraName` (`paraName`) USING BTREE,
  KEY `paraStatus` (`status`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

新建实体类

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Paraconfig implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    private Integer paraid;
    private String paraname;
    private String paracode;
    private String paradesc;
    private String status;
    public Integer getParaid() {
        return paraid;
    }
    public void setParaid(Integer paraid) {
        this.paraid = paraid;
    }
    public String getParaname() {
        return paraname;
    }
    public void setParaname(String paraname) {
        this.paraname = paraname;
    }
    public String getParacode() {
        return paracode;
    }
    public void setParacode(String paracode) {
        this.paracode = paracode;
    }
    public String getParadesc() {
        return paradesc;
    }
    public void setParadesc(String paradesc) {
        this.paradesc = paradesc;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    @Override
    public String toString() {
        return "Paraconfig [paraid=" + paraid + ", paraname=" + paraname + ", paracode=" + paracode + ", paradesc="
                + paradesc + ", status=" + status + "]";
    }

}

新建dao查询数据库接口

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.xx.model.Paraconfig;
public interface IParaConfigDao extends JpaRepository<Paraconfig,Integer>{
    public Paraconfig findByParaid(Integer id);
    public Paraconfig findByParaname(String name);
    public List findByStatus(String status);
}

新建数据库操作服务及实现

import java.util.List;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import com.xx.model.Paraconfig;
public interface IParaConfigService {
    @CacheEvict(value = "SystemCache")
    public int deletePara(int id);

    @CachePut(value = "SystemCache", key = "#para.paraid") 
    public Paraconfig addPara(Paraconfig para);

    @Cacheable(value = "SystemCache", key = "#id") 
    public Paraconfig findOne(int id);

    @Cacheable(value = "SystemCache", key = "#name") 
    public Paraconfig findByName(String name);

    @Cacheable(value = "SystemCache") 
    public List findAll();

    @Cacheable(value = "SystemCache") 
    public List findByStatus(String status);

    @CachePut(value = "SystemCache", key = "#para.paraid") 
    public Paraconfig updataPara(Paraconfig para);
}

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xx.DatabaseSservice.paraConfig.IParaConfigService;
import com.xx.dao.IParaConfigDao;
import com.xx.model.Paraconfig;

@Service
public class ParaConfigServiceImpl implements IParaConfigService{
    private Logger log=LoggerFactory.getLogger(ParaConfigServiceImpl.class);
    @Autowired
    private IParaConfigDao dao;
    @Override
    public int deletePara(int id) {
        log.info("o==||======>删除系统参数入参ID="+id);
        int result=0;
        try{
            dao.deleteById(id);
            result=0;
        }catch(Exception e){
            e.printStackTrace();
            result=-1;
            log.info("删除系统参数异常");
        }
        return result;
    }
    @Override
    public Paraconfig addPara(Paraconfig para) {
        log.info("o==||=====>新增系统参数入参:"+para.toString());
        return doExecute("addPara",null,para);
    }
    @Override
    public Paraconfig findOne(int id) {
        log.info("o==||=====>id查找系统参数入参:id="+id);
        return doExecute("findOne",String.valueOf(id),null);
    }
    @Override
    public Paraconfig findByName(String name) {
        log.info("o==||=====>name查找系统参数入参:name="+name);
        return doExecute("findByName",name,null);
    }
    @Override
    public List findAll() {
        log.info("o==||=====>查找All系统参数");
        return doExecutePage("findAll",null);
    }
    @Override
    public List findByStatus(String status) {
        log.info("o==||=====>status查找系统参数:status="+status);
        return doExecutePage("findByStatus",status);
    }
    @Override
    public Paraconfig updataPara(Paraconfig para) {
        log.info("o==||=====>更新系统参数入参:"+para.toString());
        return doExecute("updataPara",null,para);
    }

    public Paraconfig doExecute(String type,String arg,Paraconfig req){
        Paraconfig resp=new Paraconfig();
        try{
            switch(type){
                case "addPara" : ;
                case "updataPara" : resp=dao.save(req);break;
                case "findOne" : resp=dao.findByParaid(Integer.valueOf(arg));break;
                case "findByName" : resp=dao.findByParaname(arg);break;
            }
        }catch(Exception e){
            e.printStackTrace();
            String Emsg = null;
            switch(type){
                case "addPara" : Emsg="新增系统参数异常";break;
                case "updataPara" : Emsg="更新系统参数异常";break;
                case "findOne" : Emsg="根据ID查找系统参数异常";break;
                case "findByName" : Emsg="根据name查找系统参数异常";break;
            }
            log.info(Emsg+e.getMessage());
        }finally{
            log.info("查找系统参数返回:"+(resp==null?null:resp.toString()));
        }
        return resp;
    }

    public List doExecutePage(String type,String arg){
        List resp = null;
        try{
            switch(type){
                case "findAll" : resp=dao.findAll();break;
                case "findByStatus" : resp=dao.findByStatus(arg);break;
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            log.info("查找系统参数返回:"+(resp==null?null:resp.toString()));
        }
        return resp;
    }
}

新建测试controller

@PostMapping("/testCachefindOne")
    public void testCachefindOne(){
        Paraconfig para=null;
        try{
            para=paraConfigService.findOne(1);
        }catch(Exception e){
            e.printStackTrace();
            log.info("异常:"+e.getMessage());
        }
    }

测试
使用postman请求。查看控制执行数据库操作日志。
第一次请求缓存没有则有日志打印,第二次请求缓存有数据则不会打印日志。
测试没有问题说明缓存自动存储已经没问题了,接下来就是怎么取缓存及添加自定义的缓存了。
添加ehcache配置文件

  
<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="100"  
            memoryStoreEvictionPolicy="LRU" />  

    <cache  
            name="SystemCache"  
            eternal="false"  
            maxElementsInMemory="100"  
            overflowToDisk="false"  
            diskPersistent="false"  
            timeToIdleSeconds="0"  
            timeToLiveSeconds="30"  
            memoryStoreEvictionPolicy="LRU" />  
ehcache>

配置文件详解

(1).diskStore: 为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:    
user.home – 用户主目录
user.dir  – 用户当前工作目录
java.io.tmpdir – 默认临时文件路径
(2).defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
(3).cache:自定缓存策略,为自定义的缓存策略。参数解释如下:
cache元素的属性:
name:缓存名称
maxElementsInMemory:内存中最大缓存对象数
maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大
eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。
diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒
timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态
timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。

将配置文件放在src/main/resources下(或其他路径,需要配置路径)。
新建ApplicationContextUtils实现ApplicationContextAware接口

import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component  
@EnableAutoConfiguration  
public class ApplicationContextUtils implements ApplicationContextAware{
     public static ApplicationContext applicationContext=null;//可写成单利模式,这里为了方便  
     @Override  
     public void setApplicationContext(ApplicationContext arg0) throws BeansException {
         applicationContext=arg0;
         System.out.println("设置ApplicationContext成功!");
    }  
}

缓存自定义存取

@PostMapping("/testCachefindOne")
    public void testCachefindOne(){
        Paraconfig para=null;
        try{
            para=paraConfigService.findOne(1);
            EhCacheCacheManager cacheCacheManager=ApplicationContextUtils.applicationContext.getBean(EhCacheCacheManager.class); 
            //获取Cache  
            Cache cache=cacheCacheManager.getCache("SystemCache");  
            cache.put("Hello-key", "Hello-value");
            System.out.println("缓存名:"+cache.getName());
            System.out.println("缓存Hello-key:"+cache.get("Hello-key", String.class));
            System.out.println("缓存SYSDATE:"+cache.get("SYSDATE",Paraconfig.class));
        }catch(Exception e){
            e.printStackTrace();
            log.info("异常:"+e.getMessage());
        }
    }

启动测试
这里写图片描述

小结:
1.@CachePut表示缓存新添加的数据或者更新的数据到缓存中,两个参数value表示缓存的名称为SystemCache,key表示缓存的key为#id 的数据,#id为方法参数 。
2.@CacheEvict表示从缓存SystemCache中删除key为id的数据
3.@Cacheable表示添加数据到缓存中,缓存名称为SystemCache,缓存key为#para.paraid的数据。
注意: @CachePut总会执行SQL操作,其主要用在更新或插入数据时。
@Cacheable主要用在查询数据库时,缓存有则不查数据库。

你可能感兴趣的:(java)