Spring Boot缓存之EhCache

Spring Boot缓存技术

Spring Boot支持的缓存种类较多,例如EhCache、Redis、JCache 等,其中我们使用较多的是EhCache。

Spring Boot使用Cache之EhCache

  1. 首先我们可以在pom中添加依赖

    <!-- caching -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
    </dependency>
    </dependencies>
  2. 在Spring Boot配置文件中写入配置

    spring.cache.type=ehcache
    spring.cache.ehcache.config=classpath:config/ehcache.xml

    此处classpath为我们定义的缓存配置xml文件路径

  3. 创建encache.xml文件,路径和内容如下
    encache.xml路径

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="ehcache.xsd">
        <cache name="mxCache" 
            eternal="false" 
            maxEntriesLocalHeap="0"
            timeToIdleSeconds="50">
        </cache>
    </ehcache>

    eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
    maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制
    timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可无限期地处于空闲状态.

  4. 写一个EhCacheService接口

    public interface EhCacheService {
    
        User selectById(Integer id);
    
        User updateById(User user);
    
        String deleteById(Integer id);
    }
  5. 写接口的实现类EhCacheServiceImpl,代码如下

    @CacheConfig(cacheNames = "mxCache")
    @Repository
    public class EhCacheServiceImpl implements EhCacheService {
    
        @Autowired
        private TestUserDao testUserDao;
    
        @Cacheable(key = "#p0")
        @Override
        public User selectById(Integer id) {
            System.out.println("查询功能,缓存找不到,直接读库, id=" + id);
            User user = testUserDao.getOne(1);
            return user;
        }
    
        @CachePut(key = "#p0")
        @Override
        public User updateById(User user) {
            System.out.println("更新功能,更新缓存,直接写库, id=" + user);
            return testUserDao.save(user);
        }
    
        @CacheEvict(key = "#p0")
        @Override
        public String deleteById(Integer id) {
            System.out.println("删除功能,删除缓存,直接写库, id=" + id);
            return "清空缓存成功";
        }
    }

    此处@CacheConfig(cacheNames = “mxCache”)注解的cacheNames为我们在配置文件encache.xml中配置的name

  6. 创建测试的CacheController,

    @RestController
    @RequestMapping("/cache")
    public class CacheController {
    
        @Autowired
        private EhCacheService ehCacheService;
    
        @RequestMapping(value = "/select", method = RequestMethod.GET)
        public String get(@RequestParam(defaultValue = "1") Integer id) {
            User user = ehCacheService.selectById(id);
            return user.toString();
        }
    
        @RequestMapping(value = "/update", method = RequestMethod.GET)
        public String update(@RequestParam(defaultValue = "1") Integer id) {
            User user = ehCacheService.selectById(id);
            user.setUsername("测试cache");
            ehCacheService.updateById(user);
            return user.toString();
        }
    
        @RequestMapping(value = "/del", method = RequestMethod.GET)
        public String del(@RequestParam(defaultValue = "1") Integer id) {
            return ehCacheService.deleteById(id);
        }
    }
  7. 启动项目之前,在Spring Boot启动类加@EnableCaching注解

    @EnableCaching
    @SpringBootApplication
    public class SpringBootDemo9Application {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBootDemo9Application.class, args);
        }
    }
  8. 由于我们在数据库已经有一条数据,
    数据库数据
    访问测试地址http://127.0.0.1:8080/cache/select,返回页面
    select返回页面
    控制台显示,再次刷新页面,则会发现控制台不显示该语句,说明现在已经是在缓存取得数据
    select控制台显示
    访问测试地址http://127.0.0.1:8080/cache/del,返回页面
    del返回页面
    控制台显示,由于我们在代码写的删除并没有真的删除,因此这里不会真的删除数据库数据,但是已经清掉了id为1的缓存数据
    del控制台显示
    再次访问测试地址http://127.0.0.1:8080/cache/select,会发现又在数据库中取值并存于缓存中了
    访问测试地址http://127.0.0.1:8080/cache/update,返回页面
    update返回页面
    控制台显示
    update控制台显示
    此时数据库里的数据已经被更改,且缓存也同时被修改.

缓存注解解释

1、@Cacheable:主要用来配置方法,能够根据方法的请求参数对其结果进行缓存。即当重复使用相同参数调用方法的时候,方法本身不会被调用执行,即方法本身被略过了,取而代之的是方法的结果直接从缓存中找到并返回了。

参数介绍:

  • value:缓存的名字,必须指定至少一个。

  • key:缓存的key,可以为空,如果指定要按照SpEL表达式编写;如果不指定,则缺省按照方法的所有参数进行组合。

  • condition:缓存的条件,可以为空,使用SpEL编写,返回true或者false,只有为true才能缓存。

例子:

@Cacheable(value="shops:detail",key="'id:'+#p0")
public Shop getById(String id);

- 这两行代码的意思是指,缓存的名字为:shops:detail,其中缓存的key值为id:id的值。其中#p0的意思是指加有@Cacheable注解的方法中的第一个参数

2、@CacheEvict:主要对方法配置,用来标记要清空缓存的方法,当这个方法被调用并满足一定条件后,即会清空缓存。

参数解析:

  • value:缓存的位置,不能为空。
  • key:缓存的key,默认为空。
  • condition:触发的条件,只有满足条件的情况才会清楚缓存,默认为空,支持SpEL。
  • allEntries:true表示清除value中的全部缓存,默认为false。

例子:

@CacheEvict(value="shops:detail",key="'id:'+#p0['id']",condition="#p0['id']>0")
public Shop getById(Map<String, Object> param);
  • 上面两行代码表示,只要param中key为id的值大于0,将进行缓存操作,否则直接调用调用getById方法返回结果。
    @Caching(evict={@CacheEvict(value=”shops:brief”,allEntries=true)})
    public void delete(String id);

上面两行代码表示,只要执行了delete方法,就刷新缓存名为”shops:brief”下面的所有缓存。

3、@CachePut:主要针对方法的配置,能够根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用。

@CachePut(value="shops:detail",key="'id:'+#p0['id']")
public Shop update(Map<String, Object> param);
  • 上面两行代码表示,当调用update方法时,该方法体会被执行,并且执行的结果会返回写入到缓存中。

猜你喜欢

转载自blog.csdn.net/mxjesse/article/details/80588362