此文已由作者趙計剛授權網易雲社群釋出。
歡迎通路網易雲社群,了解更多網易技術産品營運經驗。
AdminCacheKey:
package com.xxx.vo.userManagement;
/**
* guava cache的key
*/
public class AdminCacheKey {
private String username;
private String password;
private int start;
private int limit;
public AdminCacheKey() {
}
public AdminCacheKey(String username, String password, int start, int limit) {
this.username = username;
this.password = password;
this.start = start;
this.limit = limit;
}
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 int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + limit;
result = prime * result
+ ((password == null) ? 0 : password.hashCode());
result = prime * result + start;
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AdminCacheKey other = (AdminCacheKey) obj;
if (limit != other.limit)
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (start != other.start)
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
}
該類是封裝了多個查詢條件的一個VO類。
2.2、ssmm0-userManagement
AdminController:
package com.xxx.web.admin;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.xxx.model.userManagement.Admin;
import com.xxx.service.userManagement.AdminService;
import com.xxx.util.admin.AdminCookieUtil;
/**
* adminController
*/
@Controller
@RequestMapping("/admin")
public class AdminController {
@Autowired
private AdminService adminService;
/**
* 管理者注冊
*/
@ResponseBody
@RequestMapping("/register")
public boolean register(@RequestParam("username") String username,
@RequestParam("password") String password){
Admin admin = new Admin();
admin.setUsername(username);
admin.setPassword(password);
boolean isRegisterSuccess = adminService.register(admin);
return isRegisterSuccess;
}
/**
* 管理者登入
*/
@RequestMapping("/login")
public ModelAndView login(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpServletResponse response,
HttpSession session){
Admin admin = adminService.login(username, password);
ModelAndView modelAndView = new ModelAndView();
if(admin == null){
modelAndView.addObject("message", "使用者不存在或者密碼錯誤!請重新輸入");
modelAndView.setViewName("error");
}else{
modelAndView.addObject("admin", admin);
modelAndView.setViewName("userinfo");
/*
* 這為什麼不直接傳一個username,而傳了一個admin,
* 是因為在實際開發中,你傳過去的資訊可能不隻是username,還有使用者手機号、位址等等
*/
//使用cookie
AdminCookieUtil.addLoginCookie(admin, response);
//使用session
//session.setAttribute("adminSession", admin);
}
return modelAndView;
}
/*****************************mybatis xml方式解決的問題*******************************/
/**
* 根據username或password查找List<Admin>
*/
@ResponseBody
@RequestMapping("/findAdmin")
public List<Admin> findAdmin(@RequestParam(value="username",required=false) String username,
@RequestParam(value="password",required=false) String password,
@RequestParam("start") int start,
@RequestParam("limit") int limit,
HttpServletRequest request,
HttpSession session){
Admin admin = AdminCookieUtil.getLoginCookie(request);
//Admin admin = (Admin) session.getAttribute("adminSession");
if(admin == null){//未登入
return null;
}
System.out.println(admin.toJson());
List<Admin> adminList = adminService.findAdmin(username, password, start, limit);
return adminList;
}
/**
* 插入一個使用者并傳回主鍵
* 注意:get請求也會自動裝配(即将前台傳入的username和password傳入admin)
*/
@ResponseBody
@RequestMapping("/insert")
public Admin insertAdminWithBackId(Admin admin){
return adminService.insertAdminWithBackId(admin);
}
/*************************guava cache******************************/
/**
* 根據username查找List<Admin>
*/
@ResponseBody
@RequestMapping("/findAdminByUsername")
public List<Admin> findAdminByUserName(@RequestParam(value="username") String username){
List<Admin> adminList = adminService.findByUsername(username);
return adminList;
}
@ResponseBody
@RequestMapping("/findAdminList")
public List<Admin> findAdminList(@RequestParam(value="username") String username,
@RequestParam(value="password",required=false) String password,
@RequestParam("start") int start,
@RequestParam("limit") int limit){
List<Admin> adminList = adminService.findAdminList(username, password, start, limit);
return adminList;
}
}
将使用到的兩個方法:
- public List<Admin> findAdminByUserName(String username)
- public List<Admin> findAdminList(String username, String password, int start, int limit)
3、測試
- 單元測試:使用springJunit去測就行
- 整體測試:代碼寫好之後,注意對代碼去做測試的方法,先運作相應的controller的方法,然後對查詢出來的部分資料在資料庫中直接進行修改,再運作之前的controller對應的方法。出現兩種結果:
- 第二次運作與第一次結果相同:緩存成功
- 第二次運作與第一次結果不同:緩存不成功
4、總結:
- 常用的幾個API:
- get(Object key):首先擷取value-->若擷取不到,先緩存-->再從緩存中去取(以上三步是原子操作),使用該方法優先于使用put
- getIfPresent(Object key):擷取value,若擷取不到,傳回null;若擷取的到,傳回value
- put(Object key, Object value):顯示的添加緩存key-value
- guava cache的get(Object key)的value不能為null(這個可以去看源代碼的注釋),看下邊的代碼例子:
注意:該代碼中的三種null情況,隻有第三種會抛出異常。前兩種不為空的原因是因為,即使admins沒有元素,admins也不會是null,而是[],這應該是mybatis的功勞?!這個是個問題,以後在讀mybatis源碼的時候,會仔細研究!!!但是實際使用中,我們判斷一個list是否為空,會使用CollectionUtil.isNotEmpty(list)類似于下邊這樣,就會抛出異常了。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 { //1、下邊這樣null的話,不抛異常 /*List<Admin> admins = adminDao.getUserByName(username); if(admins==null){ return null; } return admins;*/ //2、但是如果這裡查詢出來的結果為null的話,也沒關系 //return adminDao.getUserByName(username); //3、如果這裡直接傳回null,就會出現com.google.common.cache.CacheLoader$InvalidCacheLoadException return null; } });
但是,為了在guava cache的使用中不抛出異常,我們這裡直接使用下邊這句就好了,由mybatis将[]傳回就好了。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 { //1、下邊這樣null的話,不抛異常 List<Admin> admins = adminDao.getUserByName(username); //System.out.println(admins);//如果admins為空,不會傳回null,而是傳回[] if(CollectionUtils.isEmpty(admins)){ System.out.println(admins+"-->"); return null; } return admins; //2、但是如果這裡查詢出來的結果為null的話,也沒關系 //return adminDao.getUserByName(username); //3、如果這裡直接傳回null,就會出現com.google.common.cache.CacheLoader$InvalidCacheLoadException //return null; } });
return adminDao.getUserByName(username);
免費領取驗證碼、内容安全、短信發送、直播點播體驗包及雲伺服器等套餐
更多網易技術、産品、營運經驗分享請點選。
相關文章:
【推薦】 常見的三種撞庫方法
【推薦】 == vs === in Javascript