一、什么是缓存?
缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。
二、缓存的实现方式:
实现方式1:
内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.。
import org.springframework.stereotype.Component; import www.mxh.com.usercache.entity.UserInfo; import java.util.Calendar; import java.util.Date; import java.util.HashMap; /** * 基于hashMap实现的缓存管理 */ @Component public class UserCacheManager { /** * 用户信息缓存 */ private static HashMap<String, UserInfo> userList = new HashMap<>(); /** * 保存时间 */ private static int liveTime = 60; /** * 添加用户信息缓存 * @param sessionId * @param userInfo * @return */ public static boolean addCache(String sessionId,UserInfo userInfo){ userList.put(sessionId,userInfo); return true; } /** * 删除用户缓存信息 * @param sessionId * @return */ public static boolean delCache(String sessionId){ userList.remove(sessionId); return true; } /** * 获取用户缓存信息 * @param sessionId * @return */ public static UserInfo getCache(String sessionId){ return userList.get(sessionId); } /** * 清除过期的用户缓存信息 */ public static void clearData(){ Calendar nowTime = Calendar.getInstance(); nowTime.add(Calendar.MINUTE,-liveTime); Date time = nowTime.getTime(); for(String key : userList.keySet()){ UserInfo userInfo = userList.get(key); if(userInfo.getLogin_time() == null || time.after(userInfo.getLogin_time())){ userList.remove(key); } } } }
实现方式2(使用spring支持的cache):
实现步骤:
第一步: 导入spring-boot-starter-cache模块
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
第二步: @EnableCaching开启缓存
@SpringBootApplication @EnableCaching public class Springboot07CacheApplication { public static void main(String[] args) { SpringApplication.run(Springboot07CacheApplication.class, args); } }
第三步: 使用缓存注解
UserInfoCacheController
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import www.mxh.com.usercache.dao.LoginMapper; import www.mxh.com.usercache.entity.UserInfo; import www.mxh.com.usercache.service.Impl.LoginServiceImpl; @Scope("prototype") @Controller public class UserInfoCacheController { @Autowired(required = true) private LoginMapper loginMapper; @Autowired private LoginServiceImpl loginService; @ResponseBody @RequestMapping(value = "/user/cache/login",method = RequestMethod.GET) public void userLoginByCache(String username,String password){ UserInfo userInfo = loginService.UserLoginByCache(username, password); System.out.println(userInfo); } /** * 通过username删除单个用户缓存信息 * @param username */ @CacheEvict(value="userInfo",key="#username") @ResponseBody @RequestMapping(value = "/user/cache/delete",method = RequestMethod.GET) public void deleteUserInfoCache(String username) { System.out.println("清除用户信息缓存"); } /*@Cacheable(value="userInfo",key="#username") @ResponseBody @RequestMapping(value = "/user/cache/select",method = RequestMethod.GET) public UserInfo selectUserInfoCache(String username) { System.out.println("清除用户信息缓存"); }*/ /** * 通过username修改单个用户缓存信息 * @param username * @param password * @param age * @param sex * @param user_id * @return */ @CachePut(value="userInfo",key = "#username") @ResponseBody @RequestMapping(value = "/user/cache/update",method = RequestMethod.GET) public UserInfo updateUserInfoCache(@RequestParam(required = false) String username, @RequestParam(required = false) String password, @RequestParam(required = false) Integer age, @RequestParam(required = false) String sex, @RequestParam(required = false) Long user_id) { UserInfo userInfo = loginMapper.updateUserInfoById(username, password, age, sex, user_id); System.out.println("1.更新用户缓存信息: " + userInfo); if(null == userInfo){ userInfo = loginMapper.selectUserByUsernameAndPassword(username,password); } System.out.println("2.更新用户缓存信息: " + userInfo); return userInfo; } }
LoginServiceImpl
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import www.mxh.com.usercache.dao.LoginMapper; import www.mxh.com.usercache.entity.UserInfo; import www.mxh.com.usercache.service.LoginService; import www.mxh.com.usercache.util.UserCacheManager;
/*定义缓存名称*/ @CacheConfig(cacheNames = "userInfo") @Service public class LoginServiceImpl implements LoginService { @Autowired(required = true) private LoginMapper loginMapper;
/*将查询到的数据放入缓存,下次调用该方法会先去缓存中查询数据*/ @Cacheable(value = "userInfo", key = "#username") @Override public UserInfo UserLoginByCache(String username, String password) { UserInfo userInfo = loginMapper.selectUserByUsernameAndPasswordWithCache(username, password); System.out.println("用户缓存信息: " + userInfo); return userInfo; } }
LoginMapper
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import www.mxh.com.usercache.entity.UserInfo; /** * 登陆dao层操作接口 */ @Repository public interface LoginMapper{ @Select("select * from user_info where username=#{username} and password=#{password}") UserInfo selectUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password); @Select("select * from user_info where username=#{username} and password=#{password}") UserInfo selectUserByUsernameAndPasswordWithCache(@Param("username") String username, @Param("password") String password); @Select("update user_info set username=#{username},password=#{password},age=#{age},sex=#{sex} where user_id=#{user_id}") UserInfo updateUserInfoById(@Param("username") String username, @Param("password") String password, @Param("age") int age, @Param("sex") String sex, @Param("user_id") long user_id); /*@Select("insert into user_info (username,password,age,sex,user_id) values(#{username},#{password},#{age},#{sex},#{user_id})") UserInfo saveUserInfo(@Param("username") String username, @Param("password") String password, @Param("age") int age, @Param("sex") String sex, @Param("user_id") long user_id);*/ }
UserInfo(实体类)
import java.io.Serializable; import java.util.Date; public class UserInfo implements Serializable { private static final long serialVersionUID = 1L; private Long user_id; private String username; private String password; private String sex; private Integer age; private Date login_time; public Long getUser_id() { return user_id; } public void setUser_id(Long user_id) { this.user_id = user_id; } 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getLogin_time() { return login_time; } public void setLogin_time(Date login_time) { this.login_time = login_time; } @Override public String toString() { return "UserInfo{" + "user_id=" + user_id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", sex='" + sex + '\'' + ", age=" + age + ", login_time=" + login_time + '}'; } }
application.properties
server.port=8009 spring.datasource.url=jdbc:mysql://localhost:3306/bank?useUnicode=true&characterEncoding=utf8 spring.darasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 目标缓存管理器 #spring.cache.type=SIMPLE spring.cache.type=ehcache spring.cache.ehcache.config=classpath:ehcache.xml # 打印sql语句 logging.level.www.mxh.com.usercache.dao=debug
ehcache.xml
<ehcache> <!-- 磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存 path:指定在硬盘上存储对象的路径 path可以配置的目录有: user.home(用户的家目录) user.dir(用户当前的工作目录) java.io.tmpdir(默认的临时目录) ehcache.disk.store.dir(ehcache的配置目录) 绝对路径(如:d:\\ehcache) 查看路径方法:String tmpDir = System.getProperty("java.io.tmpdir"); --> <diskStore path="java.io.tmpdir" /> <!-- defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理 maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象 eternal:代表对象是否永不过期 (指定true则下面两项配置需为0无限期) timeToIdleSeconds:最大的发呆时间 /秒 timeToLiveSeconds:最大的存活时间 /秒 overflowToDisk:是否允许对象被写入到磁盘 说明:下列配置自缓存建立起600秒(10分钟)有效 。 在有效的600秒(10分钟)内,如果连续120秒(2分钟)未访问缓存,则缓存失效。 就算有访问,也只会存活600秒。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="true" /> <!--类中的缓存空间须在该文件中配置--> <cache name="userInfo" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="600" overflowToDisk="true" /> </ehcache>
具体代码详见博客文件中的user_cache例子