企业项目开发--本地缓存guava cache(2)
此文已由作者赵计刚授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
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(这个可以去看源代码的注释),看下边的代码例子:
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;
}
});注意:该代码中的三种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);
//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;
}
});但是,为了在guava cache的使用中不抛出异常,我们这里直接使用下边这句就好了,由mybatis将[]返回就好了。
return adminDao.getUserByName(username);
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 常见的三种撞库方法
【推荐】 == vs === in Javascript
企业项目开发--本地缓存guava cache(2)的更多相关文章
- 第七章 企业项目开发--本地缓存guava cache
1.在实际项目开发中,会使用到很多缓存技术,而且数据库的设计一般也会依赖于有缓存的情况下设计. 常用的缓存分两种:本地缓存和分布式缓存. 常用的本地缓存是guava cache,本章主要介绍guava ...
- 企业项目开发--本地缓存guava cache(1)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.在实际项目开发中,会使用到很多缓存技术,而且数据库的设计一般也会依赖于有缓存的情况下设计. 常用的缓存分 ...
- 第八章 企业项目开发--分布式缓存memcached
注意:本节代码基于<第七章 企业项目开发--本地缓存guava cache> 1.本地缓存的问题 本地缓存速度一开始高于分布式缓存,但是随着其缓存数量的增加,所占内存越来越大,系统运行内存 ...
- 企业项目开发--分布式缓存memcached(3)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 3.3.ssmm0-data 结构: 3.3.1.pom.xml 1 <?xml version=& ...
- 企业项目开发--分布式缓存Redis
第九章 企业项目开发--分布式缓存Redis(1) 注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis ...
- 第九章 企业项目开发--分布式缓存Redis(1)
注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis 1.1.为什么用分布式缓存(或者说本地缓存存在的问题 ...
- 第十章 企业项目开发--分布式缓存Redis(2)
注意:本章代码是在上一章的基础上进行添加修改,上一章链接<第九章 企业项目开发--分布式缓存Redis(1)> 上一章说了ShardedJedisPool的创建过程,以及redis五种数据 ...
- 第十一章 企业项目开发--消息队列activemq
注意:本章代码基于 第十章 企业项目开发--分布式缓存Redis(2) 代码的github地址:https://github.com/zhaojigang/ssmm0 消息队列是分布式系统中实现RPC ...
- 第六章 企业项目开发--cookie
注:本章代码基于<第五章 企业项目开发--mybatis注解与xml并用>的代码,链接如下: http://www.cnblogs.com/java-zhao/p/5120792.html ...
随机推荐
- openssl初步使用
centos平台 md5.c #include <stdio.h> #include <string.h> #include <stdlib.h> //#inclu ...
- dubbo学习(zz)
dubbo学习 博客分类: 开源软件 Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站 ...
- QualNet/EXata的发展贯穿在美军网络中心战演进的始终
QualNet/EXata的发展贯穿在美军网络中心战演进的始终 赵玉亭 1. QualNet/EXata的前身GloMoSim是美国防部高级计划研究局(DARPA)在1994年启动的全球移动信息系 ...
- 日志审计系统、事件日志审计、syslog审计
日志审计系统.事件日志审计.syslog审计 任何IT机构中的Windows机器每天都会生成巨量日志数据.这些日志包含可帮助您的有用信息: · 获取位于各个Windows事件日志严重性级别的所有网络活 ...
- 前端之 js的介绍和javascript的基础使用
一 javasvript的介绍 JavaScript概述 1 JavaScript发展史 1.1 1992年Nombas开发出C-minus-minus(--)的嵌入式的脚本语言(最初绑定在CEnvi ...
- yum 安装报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"
[root@venn09 ~]# yum install -y vim Loaded plugins: fastestmirror Could not retrieve mirrorlist http ...
- 2018.11.06 NOIP训练 简单的计数问题(计数dp)
传送门 直接f[i][j]f[i][j]f[i][j]表示已经到第iii个位置已经找到jjj个的方案数. 简单转移一下就行了. 代码
- Win7 VS2013环境编译Lua5.3.1
主要参考这篇文章,原文有几个错误顺便改正了. 在Windows下使用Visual Studio编译Lua5.3 写本文时Lua官方网站放出的新版本为5.3.1,然后我不知道为啥,神奇的国内不能访问Lu ...
- 使用hibernate从一方获取多方信息时报错:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role
引起原因:hibernate加载关联对象的方式有懒加载方式和立即加载方式. 如果在多对一的配置中没有指定加载方式,而一对多的配置中指定了懒加载方式,因此在获取一方是可获取到值,而获取多方时sessio ...
- kubeadm 双节点部署k8s v1.13.3+calico v3.3.4
一.部署环境 VMware Workstation 10 centos7 二.主机配置(每台主机都要做) 主机名 ip cpu ram master 192.168.137.10 3G node1 1 ...