大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
Redis介绍
Redis是一个开源的、高性能的、基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同场景下的缓存与存储需求,直观的存储结构使得通过程序交互十分简单。
Redis数据库中所有数据都存储在内存中,由于内存的读写速度远快于硬盘,因此Redis在性能上对比其他基于硬盘存储的数据库有非常明显的优势,而且Redis提供了对持久化的支持,即可以将内存中的数据异步写入到硬盘中,且不影响继续提供服务。
Redis提供了丰富的功能,越来愈多的人将其用作缓存、队列系统等。
Redis是开源的,良好的开发氛围和严谨的版本发布机制使得Redis的版本非常稳定可靠,如此多的公司在项目中使用了Redis也可以印证这一点。
本文内容分两块,配置文件分别单独记录
SpringBoot 2.x版本项目配置Redis数据库及使用
1.项目pom文件引入Redis依赖
<!-- kaptcha -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置application.properties
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=106.14.72.179
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1ms
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000
3.配置 RedisConfig
package com.example.demo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
4.配置 RedisService
package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
/** * 指定缓存失效时间 * @param key 键 * @param time 时间(秒) * @return */
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 根据key 获取过期时间 * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/** * 判断key是否存在 * @param key 键 * @return true 存在 false不存在 */
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 删除缓存 * @param key 可以传一个值 或多个 */
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
/** * 删除缓存 * @param keys 可以传一个值 或多个 */
@SuppressWarnings("unchecked")
public void del(Collection keys) {
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(keys)) {
redisTemplate.delete(keys);
}
}
// ============================String=============================
/** * 普通缓存获取 * @param key 键 * @return 值 */
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/** * 普通缓存放入 * @param key 键 * @param value 值 * @return true成功 false失败 */
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 普通缓存放入并设置时间 * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 递增 * @param key 键 * @param delta 要增加几(大于0) * @return */
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/** * 递减 * @param key 键 * @param delta 要减少几(小于0) * @return */
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/** * HashGet * @param key 键 不能为null * @param item 项 不能为null * @return 值 */
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/** * 获取hashKey对应的所有键值 * @param key 键 * @return 对应的多个键值 */
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/** * HashSet * @param key 键 * @param map 对应多个键值 * @return true 成功 false 失败 */
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * HashSet 并设置时间 * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) * @return true成功 false失败 */
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 向一张hash表中放入数据,如果不存在将创建 * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 向一张hash表中放入数据,如果不存在将创建 * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 * @return true 成功 false失败 */
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 删除hash表中的值 * @param key 键 不能为null * @param item 项 可以使多个 不能为null */
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/** * 删除hash表中的值 * @param key 键 不能为null * @param items 项 可以使多个 不能为null */
public void hdel(String key, Collection items) {
redisTemplate.opsForHash().delete(key, items.toArray());
}
/** * 判断hash表中是否有该项的值 * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/** * hash递增 如果不存在,就会创建一个 并把新增后的值返回 * @param key 键 * @param item 项 * @param delta 要增加几(大于0) * @return */
public double hincr(String key, String item, double delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForHash().increment(key, item, delta);
}
/** * hash递减 * @param key 键 * @param item 项 * @param delta 要减少记(小于0) * @return */
public double hdecr(String key, String item, double delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForHash().increment(key, item, -delta);
}
// ============================set=============================
/** * 根据key获取Set中的所有值 * @param key 键 * @return */
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/** * 根据value从一个set中查询,是否存在 * @param key 键 * @param value 值 * @return true 存在 false不存在 */
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 将数据放入set缓存 * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/** * 将数据放入set缓存 * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */
public long sSet(String key, Collection values) {
try {
return redisTemplate.opsForSet().add(key, values.toArray());
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/** * 将set数据放入缓存 * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/** * 获取set缓存的长度 * @param key 键 * @return */
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/** * 移除值为value的 * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/** * 获取list缓存的内容 * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 * @return */
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/** * 获取list缓存的长度 * @param key 键 * @return */
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/** * 通过索引 获取list中的值 * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 * @return */
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/** * 将list放入缓存 * @param key 键 * @param value 值 * @return */
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 将list放入缓存 * @param key 键 * @param value 值 * @param time 时间(秒) * @return */
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 将list放入缓存 * @param key 键 * @param value 值 * @return */
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 根据索引修改list中的某条数据 * @param key 键 * @param index 索引 * @param value 值 * @return */
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 移除N个值为value * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
5.至此,Redis已经配置好了,接下来是具体调用测试
package com.example.demo.controller;
import com.example.demo.converter.UserConverter;
import com.example.demo.domain.Blog;
import com.example.demo.service.BlogService;
import com.example.demo.service.RedisService;
import com.example.demo.support.ApiResponse;
import com.example.demo.support.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.Map;
@Controller
@RequestMapping("/blogs")
public class BlogController {
@Autowired
private BlogService blogService;
@Autowired
private RedisService redisService;
@RequestMapping("/{id}")
public ModelAndView blog(@PathVariable("id") Long blogId) {
ModelAndView view = new ModelAndView("blog-detail");
//查看博客信息,先根据id从Redis中找
Blog blog = (Blog) redisService.get("blog_" + blogId);
//如果Redis中没有,查询Mysql
if (blog == null) {
blog = blogService.getBlogById(blogId);
//将博客信息放入Redis,并且设置失效时间
redisService.set("blog_" + blogId, blog,60);
}
Map modelMap = view.getModelMap();
modelMap.put("userVO", UserConverter.toUserVO(UserHolder.get()));
modelMap.put("blogVO", blog);
modelMap.put("isArchives",true);
return view;
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public ApiResponse edit(Blog blogVO) {
int num = blogService.save(blogVO);
if (num == 0) {
return ApiResponse.fail().error("保存失败");
}
//新增、修改博客后,将最新的博客信息放入Redis,并且设置失效时间
redisService.set("blog_" + blogVO.getBlogId(), blogVO,60);
return ApiResponse.success().and("msg", "保存成功").and("blogId",blogVO.getBlogId());
}
}
6.完成
SpringBoot项目使用Redis做缓存
1.项目pom文件引入Cache和Redis依赖
<!-- kaptcha -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置application.properties
## Redis部分
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=106.14.72.179
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1ms
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000
## Cache部分
#缓存的名称集合,多个采用逗号分割
spring.cache.cache-names=
#缓存的类型,官方提供了很多,这里我们填写redis
spring.cache.type=redis
#是否缓存null数据,默认是false
spring.cache.redis.cache-null-values=false
#redis中缓存超时的时间,默认60000ms
spring.cache.redis.time-to-live=60000
#缓存数据key是否使用前缀,默认是true
spring.cache.redis.use-key-prefix=true
#缓存数据key的前缀,在上面的配置为true时有效,
spring.cache.redis.key-prefix=
3.配置Configuration
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Configuration
public class CacheConfig {
@Bean
CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
//common信息缓存配置
RedisCacheConfiguration userCacheConfiguration = defaultCacheConfig
// 设置 key为string序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
// 设置value为json序列化
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())).disableCachingNullValues();
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
//entryTtl设置缓存失效时间,单位是秒
redisCacheConfigurationMap.put("common", userCacheConfiguration.entryTtl(Duration.ofSeconds(30)));
//设置CacheManager的值序列化方式为JdkSerializationRedisSerializer,但其实RedisCacheConfiguration默认就是使用StringRedisSerializer序列化key,JdkSerializationRedisSerializer序列化value,所以以下注释代码为默认实现
//ClassLoader loader = this.getClass().getClassLoader();
//JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(loader);
//RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jdkSerializer);
//RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
Set<String> cacheNames = new HashSet<>();
cacheNames.add("common");
//初始化RedisCacheManager
RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory).cacheDefaults(defaultCacheConfig).initialCacheNames(cacheNames).withInitialCacheConfigurations(redisCacheConfigurationMap).build();
return cacheManager;
}
}
4.启动类Application或App加@EnableCaching注解
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
5.缓存注解的使用
- Cacheable:调用方法时先从缓存中查询有没有对应key的数据,如果有直接从缓存获取返回,如果没有则执行方法,将返回值存入缓存中。
- CacheEvict:调用方法后从缓存中删除对应key的数据
- Caching:当一个方法需要查询多个缓存或者删除多个缓存时使用
package com.example.demo.service;
import com.example.demo.domain.Blog;
import com.example.demo.domain.BlogExample;
import com.example.demo.enumdata.EnumBlogType;
import com.example.demo.mapper.BlogMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
@Service
public class BlogService {
@Resource
private BlogMapper blogMapper;
//unless 参数就是不执行Cacheable的条件
@Cacheable(value = "common", key = "'blog_'+#blogId", unless = "#blogId == null")
public Blog getBlogById (Long blogId) {
return blogMapper.selectByPrimaryKey(blogId);
}
//condition 参数就是执行Cacheable的条件
@Cacheable(value = "common", key = "'blog_by_page'",condition = "#page == null")
public List<Blog> getBlogByPage (Integer page, Integer size) {
int start = 0;
if (size == null)
size = 10;
if (page != null) {
page = page <= 0 ? 1 : page;
start = (page - 1) * size;
}
BlogExample example = new BlogExample();
example.setOrderByClause("blog_id desc limit "+ start + ","+ size);
return blogMapper.selectByExampleWithBLOBs(example);
}
@Cacheable(value = "common", key = "'blog_all'")
public List<Blog> getBlogs () {
BlogExample example = new BlogExample();
example.setOrderByClause("blog_id desc");
return blogMapper.selectByExampleWithBLOBs(example);
}
//执行下面方法需要删除三个缓存的数据,所以使用Caching
@Transactional
@Caching(evict={
@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
public int save (Blog blog) {
if (blog == null) return 0;
if (blog.getBlogId() == null) {
return insert(blog);
}
return update(blog);
}
public int insert (Blog blog) {
if (StringUtils.isBlank(blog.getAuthor()))blog.setAuthor("Cocoivan");
if (blog.getBlogType() == null)blog.setBlogType(EnumBlogType.MISCELLANEOUS.getValue());
return blogMapper.insertSelective(blog);
}
public int update (Blog blog) {
return blogMapper.updateByPrimaryKeySelective(blog);
}
}
6.注意
Spring @Cacheable、@CacheEvict、@Caching是基于Spring AOP代理类,内部方法调用时,注解是失效的。
举例子,Controller接收请求调用BlogService.save方法
缓存相关注解不生效
@Transactional
public int save (Blog blog) {
if (blog == null) return 0;
if (blog.getBlogId() == null) {
return insert(blog);
}
return update(blog);
}
@Caching(evict={
@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
public int insert (Blog blog) {
if (StringUtils.isBlank(blog.getAuthor()))blog.setAuthor("Cocoivan");
if (blog.getBlogType() == null)blog.setBlogType(EnumBlogType.MISCELLANEOUS.getValue());
return blogMapper.insertSelective(blog);
}
@Caching(evict={
@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
public int update (Blog blog) {
return blogMapper.updateByPrimaryKeySelective(blog);
}
缓存相关注解生效
@Transactional
@Caching(evict={
@CacheEvict(value = "common", key="'blog_by_page'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_all'",condition="#blog!=null")
, @CacheEvict(value = "common", key="'blog_'+#blog.blogId",condition="#blog.blogId!=null")})
public int save (Blog blog) {
if (blog == null) return 0;
if (blog.getBlogId() == null) {
return insert(blog);
}
return update(blog);
}
public int insert (Blog blog) {
if (StringUtils.isBlank(blog.getAuthor()))blog.setAuthor("Cocoivan");
if (blog.getBlogType() == null)blog.setBlogType(EnumBlogType.MISCELLANEOUS.getValue());
return blogMapper.insertSelective(blog);
}
public int update (Blog blog) {
return blogMapper.updateByPrimaryKeySelective(blog);
}
7.完成
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/190813.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...