企业项目开发--本地缓存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的使用方式,就是实际开发中最常用的方法。
相关文章:
【推荐】 质量报告之我见
【推荐】 windows下简单验证码识别——完美验证码识别系统
【推荐】 终于有人把云计算、大数据和人工智能讲明白了! (2)
企业项目开发--本地缓存guava cache(1)的更多相关文章
- 第七章 企业项目开发--本地缓存guava cache
1.在实际项目开发中,会使用到很多缓存技术,而且数据库的设计一般也会依赖于有缓存的情况下设计. 常用的缓存分两种:本地缓存和分布式缓存. 常用的本地缓存是guava cache,本章主要介绍guava ...
- 企业项目开发--本地缓存guava cache(2)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. AdminCacheKey: package com.xxx.vo.userManagement; /** ...
- 第八章 企业项目开发--分布式缓存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 ...
随机推荐
- c语言指针数组和结构体的指针
指向数组的指针,先初始化一个数组,使用传统方式遍历 void main() { ] = { ,,,, }; ; i < ; i++) { printf("%d,%x\n", ...
- MySQL主从复制解决数据库单点问题
一.单个数据库服务器的缺点 数据库服务器存在单点问题: 数据库服务器资源无法满足增长的读写请求: 高峰时数据库连接数经常超过上限. 二.如何解决单点问题 增加额外的数据库服务器,组建数据库集群: 同一 ...
- Nginx 分析access日志文件
Nginx Access Log日志统计分析常用命令 IP相关统计 统计IP访问量 awk '{print $1}' access.log | sort -n | uniq | wc -l 查看某一时 ...
- 深入了解 php 底层机制 (-)洪定坤
- Linux wget命令
一.简介 wget是一个Linux系统中的下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器.wget支持HTTP,HTTPS ...
- Luogu 2154 [SDOI2009]虔诚的墓主人
弄了很久,状态很烂…… 首先发现可用的点一共只有$1e5$个,所以可以离散化坐标来方便计算. 发现对于一个空格,设它的上.下.左.右分别有$u, d, l, r$个点,它产生的贡献是$\binom{u ...
- g++报错原因分析:expected class-name before ‘{’ token
今天写程序的时候, 遇到这样一个错误expected class-name before ‘{’ token 最后发现原来是我的头文件声明没有加. 继承时不要忘记加基类的头文件 错误: class F ...
- hive 报错 java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Unable ...
- 2018.09.24 bzoj4977: [[Lydsy1708月赛]跳伞求生(贪心+线段树)
传送门 线段树好题. 这题一看我就想贪心. 先把a,b数组排序. 然后我们选择a数组中最大的b个数(不足b个就选a个数),分别贪心出在b数组中可以获得的最大贡献. 这时可以用线段树优化. 然后交上去只 ...
- java判断字符串是否为数字,包括负数
/** * 判断是否为数字,包含负数情况 * @param str * @return */ private boolean isNumeric(String str){ Boolean flag = ...