一、案例
1.1 引入maven依賴
<!-- caching --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
1.2 配置application.properties
#echache緩存
spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:config/ehcache.xml
1.3 配置config/ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <cache name="roncooCache" eternal="false" maxEntriesLocalHeap="0" timeToIdleSeconds="50"></cache> <!-- eternal:true表示對象永不過期,此時會忽略timeToIdleSeconds和 timeToLiveSeconds屬性,默認為false --> <!-- maxEntriesLocalHeap:堆內存中最大緩存對象數,0沒有限制 --> <!-- timeToIdleSeconds: 設定允許對象處於空閑狀態的最長時間,以秒為 單位。當對象自從最近一次被訪問后,如果處於空閑狀態的時間超過了 timeToIdleSeconds屬性值,這個對象就會過期,EHCache將把它從緩存中清空。 只有當eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示對象可以 無限期地處於空閑狀態 --> </ehcache>
1.4 啟用@EnableCaching 注解支持
@EnableCaching @SpringBootApplication public class Springboot01Application { public static void main(String[] args) { SpringApplication.run(Springboot01Application.class, args); } }
1.5 編寫實體類
- 如下代碼,寫完后運行Springboot01Application.java會自動在數據庫生成表結構
package com.shyroke.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @JsonIgnoreProperties({ "handler","hibernateLazyInitializer" }) @Table(name="user") public class UserBean { @Id @GeneratedValue private Integer id; @Column private Date createTime; @Column private String userName; @Column private String userIp; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserIp() { return userIp; } public void setUserIp(String userIp) { this.userIp = userIp; } @Override public String toString() { return "RoncooUserLog [id=" + id + ", createTime=" + createTime + ", userName=" + userName + ", userIp=" + userIp + "]"; } }
1.6 編寫控制器
package com.shyroke.controller; import java.util.Date; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.shyroke.dao.UserMapper; import com.shyroke.entity.UserBean; import com.shyroke.service.CacheUserService; @Controller @RequestMapping(value = "/") public class IndexController { @Autowired private CacheUserService cacheUserService; @RequestMapping(value = "/select") @ResponseBody public UserBean get() { return cacheUserService.getUserById(1); } @RequestMapping(value = "/update") @ResponseBody public UserBean update() { UserBean bean = cacheUserService.getUserById(1); bean.setUserName("測試"); bean.setCreateTime(new Date()); cacheUserService.update(bean); return bean; } @RequestMapping(value = "/del") @ResponseBody public String del() { return cacheUserService.deleteById(1); } }
1.7 編寫服務接口和實現類
package com.shyroke.service; import com.shyroke.entity.UserBean; public interface CacheUserService { /** * 查詢 * * @param id * @return */ public UserBean getUserById(int id); /** * 更新 * * @param user * @return */ public UserBean update(UserBean user); /** * 刪除 * * @param id * @return */ public String deleteById(int id); }
package com.shyroke.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import com.shyroke.dao.UserMapper; import com.shyroke.entity.UserBean; import com.shyroke.service.CacheUserService; @CacheConfig(cacheNames = "roncooCache") @Service public class CacheUserServiceImpl implements CacheUserService{ @Autowired private UserMapper userMapper; @Cacheable(key = "#p0") @Override public UserBean getUserById(int id) { System.out.println("查詢功能,緩存找不到,直接讀庫, id=" + id); return userMapper.getOne(id); } @CachePut(key = "#p0") @Override public UserBean update(UserBean user) { System.out.println("更新功能,更新緩存,直接寫庫, id=" + user); return userMapper.save(user); } @CacheEvict(key = "#p0") @Override public String deleteById(int id) { System.out.println("刪除功能,刪除緩存,直接寫庫, id=" + id); userMapper.delete(id); return "刪除成功"; } }
1.8 編寫userMapper.java
package com.shyroke.dao; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.shyroke.entity.UserBean; public interface UserMapper extends JpaRepository<UserBean, Integer>{ }
1.9 結果
- 現在數據庫中插入一條數據
- 第一次訪問,所以沒有緩存,故發出一條sql語句查詢。
- 然后在訪問“http://localhost:8888/select” 結果如下:
沒有發出sql語句,說明是從緩存中讀取的數據。
- 測試更新結果
- 更新完畢之后,返回更新后的數據,然后在返回“http://localhost:8888/select”
- 沒有發出查詢語句,而且查詢的結果的更新世間與執行“http://localhost:8888/update”更新操作后的時間一致,說明查詢的是最新的更新后的數據,所以表示“http://localhost:8888/update”更新操作會先更新緩存。