1. 程式人生 > >Spring Boot快取之EhCache

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方法時,該方法體會被執行,並且執行的結果會返回寫入到快取中。