此文已由作者赵计刚授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

AdminCacheKey:

  1. package com.xxx.vo.userManagement;
  2.  
  3. /**
  4.  * guava cache的key
  5.  */
  6. public class AdminCacheKey {
  7.     private String username;
  8.     private String password;
  9.     private int start;
  10.     private int limit;
  11.  
  12.     public AdminCacheKey() {
  13.     }
  14.  
  15.     public AdminCacheKey(String username, String password, int start, int limit) {
  16.         this.username = username;
  17.         this.password = password;
  18.         this.start = start;
  19.         this.limit = limit;
  20.     }
  21.  
  22.     public String getUsername() {
  23.         return username;
  24.     }
  25.  
  26.     public void setUsername(String username) {
  27.         this.username = username;
  28.     }
  29.  
  30.     public String getPassword() {
  31.         return password;
  32.     }
  33.  
  34.     public void setPassword(String password) {
  35.         this.password = password;
  36.     }
  37.  
  38.     public int getStart() {
  39.         return start;
  40.     }
  41.  
  42.     public void setStart(int start) {
  43.         this.start = start;
  44.     }
  45.  
  46.     public int getLimit() {
  47.         return limit;
  48.     }
  49.  
  50.     public void setLimit(int limit) {
  51.         this.limit = limit;
  52.     }
  53.  
  54.     @Override
  55.     public int hashCode() {
  56.         final int prime = 31;
  57.         int result = 1;
  58.         result = prime * result + limit;
  59.         result = prime * result
  60.                 + ((password == null) ? 0 : password.hashCode());
  61.         result = prime * result + start;
  62.         result = prime * result
  63.                 + ((username == null) ? 0 : username.hashCode());
  64.         return result;
  65.     }
  66.  
  67.     @Override
  68.     public boolean equals(Object obj) {
  69.         if (this == obj)
  70.             return true;
  71.         if (obj == null)
  72.             return false;
  73.         if (getClass() != obj.getClass())
  74.             return false;
  75.         AdminCacheKey other = (AdminCacheKey) obj;
  76.         if (limit != other.limit)
  77.             return false;
  78.         if (password == null) {
  79.             if (other.password != null)
  80.                 return false;
  81.         } else if (!password.equals(other.password))
  82.             return false;
  83.         if (start != other.start)
  84.             return false;
  85.         if (username == null) {
  86.             if (other.username != null)
  87.                 return false;
  88.         } else if (!username.equals(other.username))
  89.             return false;
  90.         return true;
  91.     }
  92. }

该类是封装了多个查询条件的一个VO类。

2.2、ssmm0-userManagement

AdminController:

  1. package com.xxx.web.admin;
  2.  
  3. import java.util.List;
  4.  
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import javax.servlet.http.HttpSession;
  8.  
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Controller;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RequestParam;
  13. import org.springframework.web.bind.annotation.ResponseBody;
  14. import org.springframework.web.servlet.ModelAndView;
  15.  
  16. import com.xxx.model.userManagement.Admin;
  17. import com.xxx.service.userManagement.AdminService;
  18. import com.xxx.util.admin.AdminCookieUtil;
  19.  
  20. /**
  21.  * adminController
  22.  */
  23. @Controller
  24. @RequestMapping("/admin")
  25. public class AdminController {
  26.     
  27.     @Autowired
  28.     private AdminService adminService;
  29.     
  30.     /**
  31.      * 管理员注册
  32.      */
  33.     @ResponseBody
  34.     @RequestMapping("/register")
  35.     public boolean register(@RequestParam("username") String username,
  36.                             @RequestParam("password") String password){
  37.         Admin admin = new Admin();
  38.         admin.setUsername(username);
  39.         admin.setPassword(password);
  40.         
  41.         boolean isRegisterSuccess = adminService.register(admin);
  42.         
  43.         return isRegisterSuccess;
  44.     }
  45.     
  46.     /**
  47.      * 管理员登录
  48.      */
  49.     @RequestMapping("/login")
  50.     public ModelAndView login(@RequestParam("username") String username,
  51.                               @RequestParam("password") String password,
  52.                               HttpServletResponse response,
  53.                               HttpSession session){
  54.         
  55.         
  56.         Admin admin = adminService.login(username, password);
  57.         
  58.         ModelAndView modelAndView = new ModelAndView();
  59.         if(admin == null){
  60.             modelAndView.addObject("message", "用户不存在或者密码错误!请重新输入");
  61.             modelAndView.setViewName("error");
  62.         }else{
  63.             modelAndView.addObject("admin", admin);
  64.             modelAndView.setViewName("userinfo");
  65.             /*
  66.              * 这为什么不直接传一个username,而传了一个admin,
  67.              * 是因为在实际开发中,你传过去的信息可能不只是username,还有用户手机号、地址等等
  68.              */
  69.             //使用cookie
  70.             AdminCookieUtil.addLoginCookie(admin, response);
  71.             //使用session
  72.             //session.setAttribute("adminSession", admin);
  73.         }
  74.         
  75.         return modelAndView;
  76.     }
  77.     
  78.     /*****************************mybatis xml方式解决的问题*******************************/
  79.     /**
  80.      * 根据username或password查找List<Admin>
  81.      */
  82.     @ResponseBody
  83.     @RequestMapping("/findAdmin")
  84.     public List<Admin> findAdmin(@RequestParam(value="username",required=false) String username,
  85.                                     @RequestParam(value="password",required=false) String password,
  86.                                     @RequestParam("start") int start,
  87.                                     @RequestParam("limit") int limit,
  88.                                     HttpServletRequest request,
  89.                                     HttpSession session){
  90.         Admin admin = AdminCookieUtil.getLoginCookie(request);
  91.         //Admin admin = (Admin) session.getAttribute("adminSession");
  92.         
  93.         if(admin == null){//未登录
  94.             return null;
  95.         }
  96.         System.out.println(admin.toJson());
  97.         List<Admin> adminList = adminService.findAdmin(username, password, start, limit);
  98.         return adminList;
  99.     }
  100.     
  101.     /**
  102.      * 插入一个用户并返回主键
  103.      * 注意:get请求也会自动装配(即将前台传入的username和password传入admin)
  104.      */
  105.     @ResponseBody
  106.     @RequestMapping("/insert")
  107.     public Admin insertAdminWithBackId(Admin admin){
  108.         return adminService.insertAdminWithBackId(admin);
  109.     }
  110.     /*************************guava cache******************************/
  111.     /**
  112.      * 根据username查找List<Admin>
  113.      */
  114.     @ResponseBody
  115.     @RequestMapping("/findAdminByUsername")
  116.     public List<Admin> findAdminByUserName(@RequestParam(value="username") String username){
  117.         
  118.         List<Admin> adminList = adminService.findByUsername(username);
  119.         return adminList;
  120.     }
  121.     
  122.     @ResponseBody
  123.     @RequestMapping("/findAdminList")
  124.     public List<Admin> findAdminList(@RequestParam(value="username") String username,
  125.                                          @RequestParam(value="password",required=false) String password,
  126.                                          @RequestParam("start") int start,
  127.                                          @RequestParam("limit") int limit){
  128.         
  129.         List<Admin> adminList = adminService.findAdminList(username, password, start, limit);
  130.         return adminList;
  131.     }
  132. }

将使用到的两个方法:

  • 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(这个可以去看源代码的注释),看下边的代码例子:

    1.     LoadingCache<String, List<Admin>> adminListCache = CacheBuilder.newBuilder()
    2.             .expireAfterWrite(20, TimeUnit.MINUTES)// 缓存20分钟
    3.             .maximumSize(1000)// 最多缓存1000个对象
    4.             .build(new CacheLoader<String, List<Admin>>() {
    5.                 public List<Admin> load(String username) throws Exception {
    6.                     //1、下边这样null的话,不抛异常
    7.                     /*List<Admin> admins = adminDao.getUserByName(username);
    8.                     if(admins==null){
    9.                         return null; 
    10.                     }
    11.                     return admins;*/
    12.                     //2、但是如果这里查询出来的结果为null的话,也没关系
    13.                     //return adminDao.getUserByName(username);
    14.                     //3、如果这里直接返回null,就会出现com.google.common.cache.CacheLoader$InvalidCacheLoadException
    15.                     return null;
    16.                 }
    17.             });

    注意:该代码中的三种null情况,只有第三种会抛出异常。前两种不为空的原因是因为,即使admins没有元素,admins也不会是null,而是[],这应该是mybatis的功劳?!这个是个问题,以后在读mybatis源码的时候,会仔细研究!!!但是实际使用中,我们判断一个list是否为空,会使用CollectionUtil.isNotEmpty(list)类似于下边这样,就会抛出异常了。

    1.     LoadingCache<String, List<Admin>> adminListCache = CacheBuilder.newBuilder()
    2.             .expireAfterWrite(20, TimeUnit.MINUTES)// 缓存20分钟
    3.             .maximumSize(1000)// 最多缓存1000个对象
    4.             .build(new CacheLoader<String, List<Admin>>() {
    5.                 public List<Admin> load(String username) throws Exception {
    6.                     //1、下边这样null的话,不抛异常
    7.                     List<Admin> admins = adminDao.getUserByName(username);
    8.                     //System.out.println(admins);//如果admins为空,不会返回null,而是返回[]
    9.                     if(CollectionUtils.isEmpty(admins)){
    10.                         System.out.println(admins+"-->");
    11.                         return null; 
    12.                     }
    13.                     return admins;
    14.                     //2、但是如果这里查询出来的结果为null的话,也没关系
    15.                     //return adminDao.getUserByName(username);
    16.                     //3、如果这里直接返回null,就会出现com.google.common.cache.CacheLoader$InvalidCacheLoadException
    17.                     //return null;
    18.                 }
    19.             });

    但是,为了在guava cache的使用中不抛出异常,我们这里直接使用下边这句就好了,由mybatis将[]返回就好了。

    1. return adminDao.getUserByName(username);

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 常见的三种撞库方法
【推荐】 == vs === in Javascript

企业项目开发--本地缓存guava cache(2)的更多相关文章

  1. 第七章 企业项目开发--本地缓存guava cache

    1.在实际项目开发中,会使用到很多缓存技术,而且数据库的设计一般也会依赖于有缓存的情况下设计. 常用的缓存分两种:本地缓存和分布式缓存. 常用的本地缓存是guava cache,本章主要介绍guava ...

  2. 企业项目开发--本地缓存guava cache(1)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.在实际项目开发中,会使用到很多缓存技术,而且数据库的设计一般也会依赖于有缓存的情况下设计. 常用的缓存分 ...

  3. 第八章 企业项目开发--分布式缓存memcached

    注意:本节代码基于<第七章 企业项目开发--本地缓存guava cache> 1.本地缓存的问题 本地缓存速度一开始高于分布式缓存,但是随着其缓存数量的增加,所占内存越来越大,系统运行内存 ...

  4. 企业项目开发--分布式缓存memcached(3)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 3.3.ssmm0-data 结构: 3.3.1.pom.xml  1 <?xml version=& ...

  5. 企业项目开发--分布式缓存Redis

    第九章 企业项目开发--分布式缓存Redis(1) 注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis ...

  6. 第九章 企业项目开发--分布式缓存Redis(1)

    注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis 1.1.为什么用分布式缓存(或者说本地缓存存在的问题 ...

  7. 第十章 企业项目开发--分布式缓存Redis(2)

    注意:本章代码是在上一章的基础上进行添加修改,上一章链接<第九章 企业项目开发--分布式缓存Redis(1)> 上一章说了ShardedJedisPool的创建过程,以及redis五种数据 ...

  8. 第十一章 企业项目开发--消息队列activemq

    注意:本章代码基于 第十章 企业项目开发--分布式缓存Redis(2) 代码的github地址:https://github.com/zhaojigang/ssmm0 消息队列是分布式系统中实现RPC ...

  9. 第六章 企业项目开发--cookie

    注:本章代码基于<第五章 企业项目开发--mybatis注解与xml并用>的代码,链接如下: http://www.cnblogs.com/java-zhao/p/5120792.html ...

随机推荐

  1. SpringMVC学习笔记:单例与并发问题

    Spring中的Bean默认都是单例(singleton),Spring中Bean的scope属性有五种类型: singleton 表示在spring容器中的单例,通过spring容器获得该bean时 ...

  2. Python 语法糖装饰器的应用

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  3. HDU 6185(打表代码

    /** @xigua */ #include <cstdio> #include <cmath> #include <iostream> #include < ...

  4. gcc 库路径里同时有相同文件名的动态库和静态库

    找不到库的处理方案 有两种方法: 一.可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行). 二.把当前路径加 ...

  5. ubuntu安装rubyOnRails

    https://gorails.com/setup/ubuntu/16.04#ruby-rbenv 文章很详细

  6. static与非static的区别

    static 静态的,可以修饰变量或者方法 用于变量的区别 1. static 修饰的变量称为类变量或全局变量或成员变量,在类被加载的时候成员变量即被初始化,与类关联,只要类存在,static变量就存 ...

  7. linux vi操作

    1.“i”键,进入编辑状态.可以看到命令的下方出现了“--INSERT--”字样,表示成功进入了编辑模式; 2.“Esc”键,退出编辑模式.并在此时输入“:wq”以退出并保存

  8. Tensflow预测股票实例

    import pandas as pd import numpy as np import matplotlib.pyplot as plt import tensorflow as tf #———— ...

  9. python(1)在windows8.1下搭建python27和python36环境

    去Python官网下载需要的Python版本 https://www.python.org/ 我下载的是下面这两个版本: Python 2.7.13 Python 3.6.1 安装Python27时, ...

  10. mybatis的update操作的几种动态更新

    mybatis是我们开发者常用的dao框架,亿轻巧灵活为特征,在crud操作中,动态更新是常用的操作.我搜集了两种动态更新的sql写法,以备日后备用! 方法1: update loan_product ...