redis缓存添加在控制层,还是service
时间: 2023-03-21 09:00:18 浏览: 467
通常情况下,Redis缓存应该添加在Service层而不是控制层。这是因为缓存是一种跨请求和跨会话的数据存储,应该由应用程序的核心业务逻辑来处理,而控制层只是负责将请求转发到正确的Service层。
在Service层中添加Redis缓存可以带来很多好处,例如:
1. 提高性能:使用Redis缓存可以显著减少数据库查询次数,从而加速应用程序的响应速度。
2. 减少数据库负载:由于大部分请求都可以从缓存中获取数据,因此可以减轻数据库的负载。
3. 更好的伸缩性:通过将缓存放在Service层,可以在不改变控制层代码的情况下轻松地在多个服务器上扩展应用程序。
4. 更好的可维护性:通过将缓存逻辑与业务逻辑分开,可以更轻松地进行维护和调试。
当然,也有一些情况下,控制层也可以使用Redis缓存。例如,当需要缓存一些静态内容,如网站的公告或帮助信息时,可以在控制层中使用Redis缓存来提高性能。但这种情况应该是少数情况,并且应该仅限于缓存非业务相关的数据。
相关问题
springboot 使用mybatis二级缓存
Spring Boot整合MyBatis后,可以利用MyBatis的二级缓存功能来提高性能。二级缓存通常存储在内存中,用于减少数据库查询次数,特别是在数据读取频繁且数据相对静态的情况下。以下是配置和使用二级缓存的基本步骤:
1. **启用MyBatis二级缓存**: 在`mybatis-spring.xml`或application.properties(YAML)文件中,添加开启缓存的配置。例如:
```xml
<mybatis:scan base-package="com.example.mapper"/>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置二级缓存 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
```
或者
```properties
mybatis.config-location=mybatis-config.xml
```
2. **配置mybatis-config.xml** (XML配置) 或 `SqlSessionFactoryBuilderCustomizer` (Java配置) 中设置二级缓存策略,如指定缓存类型(LRU、FIFO、WEAK等)、默认的TTL(超时时间)以及是否允许分布式缓存。
3. **在Mapper接口上声明缓存级别**: 可以在Mapper接口方法上使用`@Cacheable`, `@CacheEvict`或`@Caching`注解来控制哪些方法使用缓存。比如:
```java
@Cacheable("productCache")
List<Product> getProductById(int productId);
```
4. **清理缓存**: 如果需要手动清空缓存,可以在Service层调用`SqlSession`的`clearCache()`方法。
5. **注意点**:
- 缓存仅适用于无副作用的操作,即缓存的数据不会改变其他对象的状态。
- 分布式环境需额外配置,如使用Redis作为分布式缓存解决方案。
现有如下要求,模拟博客系统中展示本周热议文章;现实体类、数据层、控制层都已书写完毕,需将业务补全。 文章Post实体如下: @Data @Accessors(chain = true) @TableName("m_post") public class Post implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Long id; private Date created; private Date modified; /** * 标题 */ @NotBlank(message = "标题不能为空") private String title; /** * 内容 */ @NotBlank(message = "内容不能为空") private String content; @NotNull(message = "分类不能为空") private Long categoryId; /** * 评论数量 */ private Integer commentCount; //其他省略 } PostMapper 数据层接口如下,注意,使用的是mybatis-plus: @Component public interface PostMapper extends BaseMapper<Post> { } 现需将业务操作补全: @Service public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService { @Autowired private RedisTemplate redisTemplate; /** * 本周热议初始化 */ @Override public void initWeekRank() { // 数据库查询获取最近7天发表的文章 // 初始化文章的总评论量,按照评论数量倒序将文章信息缓存到redis中, // 其中key值为文章id,value为文章对象,并设置7天后自动过期,注意有效时间的//计算 } }
实现本周热议文章的业务,可以按照以下步骤进行:
1. 获取最近7天发表的文章,可以使用PostMapper中的方法进行查询,例如:
```java
List<Post> posts = baseMapper.selectList(new QueryWrapper<Post>()
.ge("created", LocalDate.now().minusDays(7))
.orderByDesc("comment_count"));
```
上述代码使用了mybatis-plus提供的QueryWrapper类来构建查询条件,查询条件为created字段大于等于7天前的日期,并按照comment_count字段倒序排序,即评论数多的文章排在前面。
2. 初始化文章的总评论量,可以直接更新数据库中的comment_count字段,例如:
```java
posts.forEach(post -> {
int commentCount = commentService.count(new QueryWrapper<Comment>()
.eq("post_id", post.getId()));
post.setCommentCount(commentCount);
baseMapper.updateById(post);
});
```
上述代码使用了mybatis-plus提供的updateById方法更新数据库中的记录,并且在更新时计算了文章的评论数量并赋值给commentCount字段。
3. 将文章信息缓存到redis中,可以使用redisTemplate的opsForValue方法进行操作,例如:
```java
long expireTime = 7 * 24 * 60 * 60; // 7天的秒数
posts.forEach(post -> {
String key = "week:rank:" + post.getId();
redisTemplate.opsForValue().set(key, post, expireTime, TimeUnit.SECONDS);
});
```
上述代码将文章对象存储到redis中,并且设置了7天后自动过期,过期时间的计算使用了TimeUnit提供的SECONDS常量。
完整的PostServiceImpl代码如下:
```java
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private CommentService commentService;
/**
* 本周热议初始化
*/
@Override
public void initWeekRank() {
// 数据库查询获取最近7天发表的文章
List<Post> posts = baseMapper.selectList(new QueryWrapper<Post>()
.ge("created", LocalDate.now().minusDays(7))
.orderByDesc("comment_count"));
// 初始化文章的总评论量
posts.forEach(post -> {
int commentCount = commentService.count(new QueryWrapper<Comment>()
.eq("post_id", post.getId()));
post.setCommentCount(commentCount);
baseMapper.updateById(post);
});
// 按照评论数量倒序将文章信息缓存到redis中
long expireTime = 7 * 24 * 60 * 60; // 7天的秒数
posts.forEach(post -> {
String key = "week:rank:" + post.getId();
redisTemplate.opsForValue().set(key, post, expireTime, TimeUnit.SECONDS);
});
}
}
```
上述代码中,注入了CommentService来计算文章的评论数量,具体实现可以根据实际情况进行编写。另外,需要注意缓存的key值命名规则,这里使用了"week:rank:"作为前缀。
阅读全文