Contents
1. redis 缓存
Spring Cache 提供了 @Cacheable 、@CachePut 、@CacheEvict 、@Caching 等注解,在方法上使用。
@Cacheable
注解
1.@EnableCaching
一般用在启动类上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<br />@Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport{ //缓存管理器 @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheManager cacheManager = RedisCacheManager.builder(factory).build(); return cacheManager; } //自定义缓存key生成策略 @Bean @Override public KeyGenerator keyGenerator() { return new KeyGenerator(){ @Override public Object generate(Object target, java.lang.reflect.Method method, Object... params) { StringBuffer sb = new StringBuffer(); sb.append(target.getClass().getName()); sb.append(method.getName()); for(Object obj:params){ sb.append(obj.toString()); } System.out.println("调用Redis生成key:"+sb.toString()); return sb.toString(); } }; } } |
2.@CacheConfig
当我们需要缓存的地方越来越多,你可以使用@CacheConfig(cacheNames = {"cacheName"})注解在 class 之上来统一指定value的值,这时可省略value,如果你在你的方法依旧写上了value,那么依然以方法的value值为准。
3.@Cacheable
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。 查看源码,属性值如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Cacheable { @AliasFor("cacheNames") String[] value() default {}; // value 缓存名,必填,它指定了你的缓存存放在哪块命名空间 @AliasFor("value") String[] cacheNames() default {}; // cacheNames 与 value 差不多,二选一即可 String key() default ""; // key 可选属性,可以使用 SpEL 标签自定义缓存的key String keyGenerator() default ""; // key的生成器。key/keyGenerator二选一使用 String cacheManager() default ""; // cacheManager 指定缓存管理器 String cacheResolver() default ""; // cacheResolver 指定获取解析器 String condition() default ""; // condition 条件符合则缓存 String unless() default ""; // unless 条件符合则不缓存 boolean sync() default false; // sync 是否使用异步模式,默认为false } |
4.@CachePut
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。 查看源码,属性值如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface CachePut { @AliasFor("cacheNames") String[] value() default {}; // value 缓存名,必填,它指定了你的缓存存放在哪块命名空间 @AliasFor("value") String[] cacheNames() default {}; // cacheNames 与 value 差不多,二选一即可 String key() default ""; // key可选属性,可以使用 SpEL 标签自定义缓存的key String keyGenerator() default ""; // keyGeneratorkey的生成器。key/keyGenerator二选一使用 String cacheManager() default ""; //cacheManager指定缓存管理器 String cacheResolver() default ""; // cacheResolver指定获取解析器 String condition() default ""; // condition条件符合则缓存 String unless() default ""; //unless条件符合则不缓存 } |
5.@CacheEvict
使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上 查看源码,属性值如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface CacheEvict { @AliasFor("cacheNames") String[] value() default {}; // value 缓存名,必填,它指定了你的缓存存放在哪块命名空间 @AliasFor("value") String[] cacheNames() default {}; // cacheNames 与 value 差不多,二选一即可 String key() default ""; // key可选属性,可以使用 SpEL 标签自定义缓存的key String keyGenerator() default ""; // keyGeneratorkey的生成器。key/keyGenerator二选一使用 String cacheManager() default ""; //cacheManager指定缓存管理器 String cacheResolver() default ""; // cacheResolver指定获取解析器 String condition() default ""; // condition条件符合则缓存 String unless() default ""; //unless条件符合则不缓存 } |
6.@Caching
该注解可以实现同一个方法上同时使用多种注解。可从其源码看出:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Caching { Cacheable[] cacheable() default {}; CachePut[] put() default {}; CacheEvict[] evict() default {}; } |
RedisConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package cn.zycfc.weblogin.config; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport{ //缓存管理器 @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheManager cacheManager = RedisCacheManager.builder(factory).build(); return cacheManager; } //自定义缓存key生成策略 @Bean @Override public KeyGenerator keyGenerator() { return new KeyGenerator(){ @Override public Object generate(Object target, java.lang.reflect.Method method, Object... params) { StringBuffer sb = new StringBuffer(); sb.append(target.getClass().getName()); sb.append(method.getName()); for(Object obj:params){ sb.append(obj.toString()); } System.out.println("调用Redis生成key:"+sb.toString()); return sb.toString(); } }; } } |
Pom.xml 添加
1 2 3 4 5 6 7 |
<br /><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.2.1.RELEASE</version> </dependency> |
application.properties 配置文件
1 2 3 4 5 6 7 8 9 10 |
#redis 配置 #database name spring.redis.database=0 #server host spring.redis.host=xx.188.109 #server password spring.redis.password=123456 #connection port spring.redis.port=6379 |
实体类 必須繼承Serializable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package cn.zycfc.weblogin.entity; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import java.io.Serializable; @Data public class User implements Serializable { @Id private Integer id; @Column(name = "name") private String name; @Column(name = "pwd") private String pwd; } |
数据层 dao 和 mapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public interface UserDao { //mapper.xml方式 /** * 获取所有用户 * @return */ List<UserEntity> getAll(); /** * 根据id获取用户 * @return */ UserEntity getOne(Long id); /** * 新增用户 * @param user */ void insertUser(UserEntity user); /** * 修改用户 * @param user */ void updateUser(UserEntity user); /** * 删除用户 * @param id */ void deleteUser(Long id); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.zwqh.springboot.dao.UserDao"> <resultMap type="cn.zwqh.springboot.model.UserEntity" id="user"> <id property="id" column="id"/> <result property="userName" column="user_name"/> <result property="userSex" column="user_sex"/> </resultMap> <!-- 获取所有用户 --> <select id="getAll" resultMap="user"> select * from t_user </select> <!-- 根据用户ID获取用户 --> <select id="getOne" resultMap="user"> select * from t_user where id=#{id} </select> <!-- 新增用户 --> <insert id="insertUser" parameterType="cn.zwqh.springboot.model.UserEntity"> insert into t_user (user_name,user_sex) values(#{userName},#{userSex}) </insert> <!-- 修改用户 --> <update id="updateUser" parameterType="cn.zwqh.springboot.model.UserEntity"> update t_user set user_name=#{userName},user_sex=#{userSex} where id=#{id} </update> <!-- 删除用户 --> <delete id="deleteUser" parameterType="Long"> delete from t_user where id=#{id} </delete> </mapper> |
业务代码层接口 Service 和实现类 ServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public interface UserService { /** * 查找所有 * @return */ List<UserEntity> getAll(); /** * 根据id获取用户 * @param id * @return */ UserEntity getOne(Long id); /** * 新增用户 * @param user */ void insertUser(UserEntity user); /** * 修改用户 * @param user */ void updateUser(UserEntity user); void deleteAll1(); void deleteAll12(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
@Service @CacheConfig(cacheNames = {"userCache"}) public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override @Cacheable("userList") // 标志读取缓存操作,如果缓存不存在,则调用目标方法,并将结果放入缓存 public List<UserEntity> getAll() { System.out.println("缓存不存在,执行方法"); return userDao.getAll(); } @Override @Cacheable(cacheNames = { "user" }, key = "#id")//如果缓存存在,直接读取缓存值;如果缓存不存在,则调用目标方法,并将结果放入缓存 public UserEntity getOne(Long id) { System.out.println("缓存不存在,执行方法"); return userDao.getOne(id); } @Override @CachePut(cacheNames = { "user" }, key = "#user.id")//写入缓存,key为user.id,一般该注解标注在新增方法上 public void insertUser(UserEntity user) { System.out.println("写入缓存"); userDao.insertUser(user); } @Override @CacheEvict(cacheNames = { "user" }, key = "#user.id")//根据key清除缓存,一般该注解标注在修改和删除方法上 public void updateUser(UserEntity user) { System.out.println("清除缓存"); userDao.updateUser(user); } @Override @CacheEvict(value="userCache",allEntries=true)//方法调用后清空所有缓存 public void deleteAll1() { } @Override @CacheEvict(value="userCache",beforeInvocation=true)//方法调用前清空所有缓存 public void deleteAll2() { } } |
测试 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; /** * 查找所有 * @return */ @RequestMapping("/getAll") public List<UserEntity> getAll(){ return userService.getAll(); } /** * 根据id获取用户 * @return */ @RequestMapping("/getOne") public UserEntity getOne(Long id){ return userService.getOne(id); } /** * 新增用户 * @param user * @return */ @RequestMapping("/insertUser") public String insertUser(UserEntity user) { userService.insertUser(user); return "insert success"; } /** * 修改用户 * @param user * @return */ @RequestMapping("/updateUser") public String updateUser(UserEntity user) { userService.updateUser(user); return "update success"; } } |
##### 启动 Cache 功能
1 2 3 4 5 6 7 8 9 10 11 |
@SpringBootApplication @MapperScan("cn.zwqh.springboot.dao") @EnableCaching //启动 Cache 功能 public class SpringBootCacheApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCacheApplication.class, args); } } |

