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

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

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的使用方式,就是实际开发中最常用的方法。

相关文章:
【推荐】 质量报告之我见
【推荐】 windows下简单验证码识别——完美验证码识别系统
【推荐】 终于有人把云计算、大数据和人工智能讲明白了! (2)

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

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

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

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

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. AdminCacheKey: package com.xxx.vo.userManagement; /** ...

  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. [leetcode]117. Populating Next Right Pointers in Each NodeII用next填充同层相邻节点

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...

  2. 11-简单解释spingmvc项目的结构

    可以简单的理解为下面这样子:

  3. iframe父窗口和子窗口之间的调用

    1>父窗口获取子窗口 js方法 document.getElementById('if1').contentWindow.document: window.frames["if1&qu ...

  4. JSP的内置对象application、session、request、page的作用域

    1.application内置对象的类型名称为ServletContext. 2.session内置对象的类型名称为HttpSession. 3.application作用域:对应整个应用上下文. a ...

  5. VC2008 类型重定义的问题

    Q: 比如"a.h"里定义了类a,类a所有函数的实现都放在"a.cpp"里.然后"b.h"和"c.h"都需要用到类a,所 ...

  6. win7系统administrator用户提示没有管理员权限,造装驱动安装错误,软件无法使用

    警告1909.无法创建快捷方式 最近使用windows 7 32位安装软件,好多都失败.出现以上类似错误. 解决方法:在系统盘(C:)右键属性“安全”选项卡--“编辑”,添加“Everyone”设置为 ...

  7. Django基础教程

    实例练习1-提交数据并展示 1.app_01下的views.py info_list=[] def userInfor(req): if req.method=="POST": u ...

  8. phython学习

    Python 中文学习大本营 关于作者 赞助本站 The Python Tutorial (Python 2.7.X) 的中文翻译版本.Python Tutorial 为初学 Python 必备官方教 ...

  9. SQL思维导图

  10. Ubuntu12.04添加环境变量

    环境变量分为系统级和用户级. 系统级变量设置环境为/etc/environment和/etc/profile等,不要轻易修改,否则可能造成系统错误. 用户级变量设置路径为-/.bashrc和~/.pr ...