一、什么是緩存?
緩存,就是將程序或系統經常要調用的對象存在內存中,以便其使用時可以快速調用,不必再去創建新的重復的實例。這樣做可以減少系統開銷,提高系統效率。
二、緩存的實現方式:
實現方式1:
內存緩存,也就是實現一個類中靜態Map,對這個Map進行常規的增刪查.。
import org.springframework.stereotype.Component; import www.mxh.com.usercache.entity.UserInfo; import java.util.Calendar; import java.util.Date; import java.util.HashMap; /** * 基於hashMap實現的緩存管理 */ @Component public class UserCacheManager { /** * 用戶信息緩存 */ private static HashMap<String, UserInfo> userList = new HashMap<>(); /** * 保存時間 */ private static int liveTime = 60; /** * 添加用戶信息緩存 * @param sessionId * @param userInfo * @return */ public static boolean addCache(String sessionId,UserInfo userInfo){ userList.put(sessionId,userInfo); return true; } /** * 刪除用戶緩存信息 * @param sessionId * @return */ public static boolean delCache(String sessionId){ userList.remove(sessionId); return true; } /** * 獲取用戶緩存信息 * @param sessionId * @return */ public static UserInfo getCache(String sessionId){ return userList.get(sessionId); } /** * 清除過期的用戶緩存信息 */ public static void clearData(){ Calendar nowTime = Calendar.getInstance(); nowTime.add(Calendar.MINUTE,-liveTime); Date time = nowTime.getTime(); for(String key : userList.keySet()){ UserInfo userInfo = userList.get(key); if(userInfo.getLogin_time() == null || time.after(userInfo.getLogin_time())){ userList.remove(key); } } } }
實現方式2(使用spring支持的cache):
實現步驟:
第一步: 導入spring-boot-starter-cache模塊
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
第二步: @EnableCaching開啟緩存
@SpringBootApplication @EnableCaching public class Springboot07CacheApplication { public static void main(String[] args) { SpringApplication.run(Springboot07CacheApplication.class, args); } }
第三步: 使用緩存注解
UserInfoCacheController
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import www.mxh.com.usercache.dao.LoginMapper; import www.mxh.com.usercache.entity.UserInfo; import www.mxh.com.usercache.service.Impl.LoginServiceImpl; @Scope("prototype") @Controller public class UserInfoCacheController { @Autowired(required = true) private LoginMapper loginMapper; @Autowired private LoginServiceImpl loginService; @ResponseBody @RequestMapping(value = "/user/cache/login",method = RequestMethod.GET) public void userLoginByCache(String username,String password){ UserInfo userInfo = loginService.UserLoginByCache(username, password); System.out.println(userInfo); } /** * 通過username刪除單個用戶緩存信息 * @param username */ @CacheEvict(value="userInfo",key="#username") @ResponseBody @RequestMapping(value = "/user/cache/delete",method = RequestMethod.GET) public void deleteUserInfoCache(String username) { System.out.println("清除用戶信息緩存"); } /*@Cacheable(value="userInfo",key="#username") @ResponseBody @RequestMapping(value = "/user/cache/select",method = RequestMethod.GET) public UserInfo selectUserInfoCache(String username) { System.out.println("清除用戶信息緩存"); }*/ /** * 通過username修改單個用戶緩存信息 * @param username * @param password * @param age * @param sex * @param user_id * @return */ @CachePut(value="userInfo",key = "#username") @ResponseBody @RequestMapping(value = "/user/cache/update",method = RequestMethod.GET) public UserInfo updateUserInfoCache(@RequestParam(required = false) String username, @RequestParam(required = false) String password, @RequestParam(required = false) Integer age, @RequestParam(required = false) String sex, @RequestParam(required = false) Long user_id) { UserInfo userInfo = loginMapper.updateUserInfoById(username, password, age, sex, user_id); System.out.println("1.更新用戶緩存信息: " + userInfo); if(null == userInfo){ userInfo = loginMapper.selectUserByUsernameAndPassword(username,password); } System.out.println("2.更新用戶緩存信息: " + userInfo); return userInfo; } }
LoginServiceImpl
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import www.mxh.com.usercache.dao.LoginMapper; import www.mxh.com.usercache.entity.UserInfo; import www.mxh.com.usercache.service.LoginService; import www.mxh.com.usercache.util.UserCacheManager;
/*定義緩存名稱*/ @CacheConfig(cacheNames = "userInfo") @Service public class LoginServiceImpl implements LoginService { @Autowired(required = true) private LoginMapper loginMapper;
/*將查詢到的數據放入緩存,下次調用該方法會先去緩存中查詢數據*/ @Cacheable(value = "userInfo", key = "#username") @Override public UserInfo UserLoginByCache(String username, String password) { UserInfo userInfo = loginMapper.selectUserByUsernameAndPasswordWithCache(username, password); System.out.println("用戶緩存信息: " + userInfo); return userInfo; } }
LoginMapper
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import www.mxh.com.usercache.entity.UserInfo; /** * 登陸dao層操作接口 */ @Repository public interface LoginMapper{ @Select("select * from user_info where username=#{username} and password=#{password}") UserInfo selectUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password); @Select("select * from user_info where username=#{username} and password=#{password}") UserInfo selectUserByUsernameAndPasswordWithCache(@Param("username") String username, @Param("password") String password); @Select("update user_info set username=#{username},password=#{password},age=#{age},sex=#{sex} where user_id=#{user_id}") UserInfo updateUserInfoById(@Param("username") String username, @Param("password") String password, @Param("age") int age, @Param("sex") String sex, @Param("user_id") long user_id); /*@Select("insert into user_info (username,password,age,sex,user_id) values(#{username},#{password},#{age},#{sex},#{user_id})") UserInfo saveUserInfo(@Param("username") String username, @Param("password") String password, @Param("age") int age, @Param("sex") String sex, @Param("user_id") long user_id);*/ }
UserInfo(實體類)
import java.io.Serializable; import java.util.Date; public class UserInfo implements Serializable { private static final long serialVersionUID = 1L; private Long user_id; private String username; private String password; private String sex; private Integer age; private Date login_time; public Long getUser_id() { return user_id; } public void setUser_id(Long user_id) { this.user_id = user_id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getLogin_time() { return login_time; } public void setLogin_time(Date login_time) { this.login_time = login_time; } @Override public String toString() { return "UserInfo{" + "user_id=" + user_id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", sex='" + sex + '\'' + ", age=" + age + ", login_time=" + login_time + '}'; } }
application.properties
server.port=8009 spring.datasource.url=jdbc:mysql://localhost:3306/bank?useUnicode=true&characterEncoding=utf8 spring.darasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 目標緩存管理器 #spring.cache.type=SIMPLE spring.cache.type=ehcache spring.cache.ehcache.config=classpath:ehcache.xml # 打印sql語句 logging.level.www.mxh.com.usercache.dao=debug
ehcache.xml
<ehcache> <!-- 磁盤存儲:將緩存中暫時不使用的對象,轉移到硬盤,類似於Windows系統的虛擬內存 path:指定在硬盤上存儲對象的路徑 path可以配置的目錄有: user.home(用戶的家目錄) user.dir(用戶當前的工作目錄) java.io.tmpdir(默認的臨時目錄) ehcache.disk.store.dir(ehcache的配置目錄) 絕對路徑(如:d:\\ehcache) 查看路徑方法:String tmpDir = System.getProperty("java.io.tmpdir"); --> <diskStore path="java.io.tmpdir" /> <!-- defaultCache:默認的緩存配置信息,如果不加特殊說明,則所有對象按照此配置項處理 maxElementsInMemory:設置了緩存的上限,最多存儲多少個記錄對象 eternal:代表對象是否永不過期 (指定true則下面兩項配置需為0無限期) timeToIdleSeconds:最大的發呆時間 /秒 timeToLiveSeconds:最大的存活時間 /秒 overflowToDisk:是否允許對象被寫入到磁盤 說明:下列配置自緩存建立起600秒(10分鍾)有效 。 在有效的600秒(10分鍾)內,如果連續120秒(2分鍾)未訪問緩存,則緩存失效。 就算有訪問,也只會存活600秒。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="true" /> <!--類中的緩存空間須在該文件中配置--> <cache name="userInfo" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="600" overflowToDisk="true" /> </ehcache>
具體代碼詳見博客文件中的user_cache例子