此文已由作者赵计刚授权网易云社区发布。
欢迎访问,了解更多网易技术产品运营经验。
1、在实际项目开发中,会使用到很多缓存技术,而且数据库的设计一般也会依赖于有缓存的情况下设计。
常用的缓存分两种:本地缓存和分布式缓存。
常用的本地缓存是guava cache,本章主要介绍guava cache在项目中的使用。
关于常用缓存以及每种缓存常用场景的介绍,之后可以去查看我记录的"Java缓存相关"系列博客。链接如下:
《》
2、实际使用
本项目的代码基于第六章的代码进行构建,这里只列出修改过的代码:
2.1、ssmm0-data
pom.xml:
com.google.guava guava 14.0.1
在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 ListgetAdminByConditions(@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 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 */@Repositorypublic 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 ListfindAdmin(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 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 */@Servicepublic 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 ListfindAdmin(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 findByUsername(String username) { List adminList = null; try { adminList = adminListCache.get(username); } catch (ExecutionException e) { e.printStackTrace(); } return adminList; } LoadingCache > adminListCache = CacheBuilder.newBuilder() .expireAfterWrite(20, TimeUnit.MINUTES)// 缓存20分钟 .maximumSize(1000)// 最多缓存1000个对象 .build(new CacheLoader >() { public List load(String username) throws Exception { return adminDao.getUserByName(username); } }); /************多条件的查询,key为Object(封装了多个条件的VO类)***********/ public List 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 adminList = null; try { System.out.println(cacheKey); adminList = adminsCache.get(cacheKey); } catch (ExecutionException e) { e.printStackTrace(); } return adminList; } LoadingCache > adminsCache = CacheBuilder.newBuilder() .expireAfterWrite(60, TimeUnit.MINUTES) // 缓存项在给定时间内(60min)没有被写访问(创建或覆盖),则回收 .maximumSize(100) // 最多缓存100项 .build(new CacheLoader >() { public List 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的使用方式,就是实际开发中最常用的方法。
相关文章:
【推荐】 【推荐】 【推荐】