企業專案開發--本地快取guava cache(1)
此文已由作者趙計剛授權網易雲社群釋出。
歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。
1、在實際專案開發中,會使用到很多快取技術,而且資料庫的設計一般也會依賴於有快取的情況下設計。
常用的快取分兩種:本地快取和分散式快取。
常用的本地快取是guava cache,本章主要介紹guava cache在專案中的使用。
關於常用快取以及每種快取常用場景的介紹,之後可以去檢視我記錄的"Java快取相關"系列部落格。連結如下:
2、實際使用
本專案的程式碼基於第六章的程式碼進行構建,這裡只列出修改過的程式碼:
2.1、ssmm0-data
pom.xml:
<!-- guava cache --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>14.0.1</version> </dependency>
在pom.xml中引入了guava cache14.0.1的依賴包。
AdminMapper:
package com.xxx.mapper.userManagement; import java.util.List; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import com.xxx.model.userManagement.Admin; /** * 管理員Mapper */ public interface AdminMapper { /**************註解**************/ @Insert("INSERT INTO userinfo(username, password) VALUES(#{username},#{password})") public int insertAdmin(Admin admin); @Select("SELECT * FROM userinfo WHERE username = #{username} AND password = #{password}") @Results(value = { @Result(id = true, column = "id", property = "id"), @Result(column = "username", property = "username"), @Result(column = "password", property = "password") }) public Admin selectAdmin(@Param("username") String username, @Param("password") String password); /***************xml**************/ /** * 條件不定式查詢 * 我們這裡使用@Param指定引數,這樣的話,在AdminMapper.xml中就不用再使用parameterType屬性了;否則得寫parameterType屬性 */ public List<Admin> getAdminByConditions(@Param("username")String username, @Param("password")String password, @Param("start")int start, @Param("limit")int limit); /** * 返回主鍵 */ public int insertAdminWithBackId(Admin admin); /****************guava cache*****************/ @Select("SELECT * FROM userinfo WHERE username = #{username}") @Results(value = { @Result(id = true, column = "id", property = "id"), @Result(column = "username", property = "username"), @Result(column = "password", property = "password") }) public List<Admin> getUserByName(@Param("username") String username); }
將使用到的兩個方法:
public List<Admin> getUserByName(String username)
public List<Admin> getAdminByConditions(String username, String password, int start, int limit)
AdminDao:
package com.xxx.dao.userManagement; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.xxx.mapper.userManagement.AdminMapper; import com.xxx.model.userManagement.Admin; /** * 管理員DAO */ @Repository public class AdminDao { @Autowired private AdminMapper adminMapper; /***************註解*****************/ public boolean register(Admin admin){ return adminMapper.insertAdmin(admin)==1?true:false; } public Admin login(String username ,String password){ return adminMapper.selectAdmin(username, password); } /****************xml******************/ public List<Admin> findAdmin(String username, String password, int start, int limit){ return adminMapper.getAdminByConditions(username, password, start, limit); } public int insertAdminWithBackId(Admin admin){ return adminMapper.insertAdminWithBackId(admin); } /******************guava cache********************/ public List<Admin> getUserByName(String username){ return adminMapper.getUserByName(username); } }
將使用到的兩個方法:
public List<Admin> getUserByName(String username)
public List<Admin> findAdmin(String username, String password, int start, int limit)
AdminService:
package com.xxx.service.userManagement; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.xxx.dao.userManagement.AdminDao; import com.xxx.model.userManagement.Admin; import com.xxx.vo.userManagement.AdminCacheKey; /** * 管理員service */ @Service public class AdminService { @Autowired private AdminDao adminDao; public boolean register(Admin admin) { return adminDao.register(admin); } public Admin login(String username, String password) { return adminDao.login(username, password); } /*********** 以下方法是為了測試mybatis中使用xml **********/ public List<Admin> findAdmin(String username, String password, int start, int limit) { return adminDao.findAdmin(username, password, start, limit); } public Admin insertAdminWithBackId(Admin admin) { int record = adminDao.insertAdminWithBackId(admin); if (record == 1) { return admin;// 這時的admin已經被賦予主鍵了 } return null; } /************************ guava cache *************************/ /************單條件的查詢,key為String***********/ public List<Admin> findByUsername(String username) { List<Admin> adminList = null; try { adminList = adminListCache.get(username); } catch (ExecutionException e) { e.printStackTrace(); } return adminList; } LoadingCache<String, List<Admin>> adminListCache = CacheBuilder.newBuilder() .expireAfterWrite(20, TimeUnit.MINUTES)// 快取20分鐘 .maximumSize(1000)// 最多快取1000個物件 .build(new CacheLoader<String, List<Admin>>() { public List<Admin> load(String username) throws Exception { return adminDao.getUserByName(username); } }); /************多條件的查詢,key為Object(封裝了多個條件的VO類)***********/ public List<Admin> findAdminList(String username, String password, int start, int limit) { /* * 注意: * 如果以一個新建的物件做為key的話,因為每次都是新建一個物件,所以這樣的話,實際上每次訪問key都是不同的,即每次訪問都是重新進行快取; * 但是實際上,我們想要根據物件的屬性來判斷物件是否相等,只需要根據這些屬性重寫物件的hashCode與equals方法即可, * 所以重寫了AdminCacheKey類的hashCode和equals方法,這樣,每次訪問的話,就會以每個條件是否相等來判斷物件(即key)是否相等了,這一塊兒的快取就會起作用了 */ AdminCacheKey cacheKey = new AdminCacheKey(username, password, start, limit); List<Admin> adminList = null; try { System.out.println(cacheKey); adminList = adminsCache.get(cacheKey); } catch (ExecutionException e) { e.printStackTrace(); } return adminList; } LoadingCache<AdminCacheKey, List<Admin>> adminsCache = CacheBuilder.newBuilder() .expireAfterWrite(60, TimeUnit.MINUTES) // 快取項在給定時間內(60min)沒有被寫訪問(建立或覆蓋),則回收 .maximumSize(100) // 最多快取100項 .build(new CacheLoader<AdminCacheKey, List<Admin>>() { public List<Admin> load(AdminCacheKey key) throws Exception { return adminDao.findAdmin(key.getUsername(), key.getPassword(), key.getStart(), key.getLimit()); } }); }
將使用到的兩個方法:
public List<Admin> findByUsername(String username)
public List<Admin> findAdminList(String username, String password, int start, int limit)
這一塊兒是整個guava cache使用的部分。這裡邊寫出了兩種guava cache使用的方式:
單查詢條件:key為String或Object都可以
多查詢條件:key為Object,該Object封裝了多個查詢條件,並通過這些查詢條件重寫了該Object的hashcode()和equals()
這一部分中guava cache的使用方式,就是實際開發中最常用的方法。
相關文章:
【推薦】 感動到流淚!資料分析師的福音:跨檢視粒度計算