题目:
模拟一个微博的热搜
表: tb_news id title
Redis: zset
例:
1.创建一个实体类 NewsEntity
package com.lanou3g.redisdemo.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
/**
* 创建人: 武奇
* 创建事件: 2019/6/26
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "tb_news")
public class NewsEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@Transient
private Double score;
}
2 创建. NewsRepository 接口继承JpaRepository 接口(继承后可根据方法名自动生成sql语句)package com.lanou3g.redisdemo.repository;
import com.lanou3g.redisdemo.entity.NewsEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
- 创建人: 武奇
创建事件: 2019/6/26
*/
public interface NewsRepository extends JpaRepository{ List findByIdIn(List idList);
}
3.编写前端导入JQ 向后台发送请求
新闻列表
4.创建controller 层接收前端发送过来的请求
@RestController
@RequestMapping("/news")
public class NewsController {
// 引入NewsService 接口
@Resource
private NewsService newsService;
// 查询所有
@RequestMapping("/list")
public List list() {
return this.newsService.findAll();
}
// 增加点击数量 (Id 的添加)
@RequestMapping("/like")
public Map like(Long id) {
this.newsService.likeId(id);
return Collections.singletonMap("message", "OK");
}
// 向前端返回集合(id 的返回)
@RequestMapping("/sort")
public Collection> sort() {
return this.newsService.getWithScoresId();
}
创建 newservice 接口 (接口中写了两种添加 到 redis方式)
public interface NewsService {
// 查新所有新闻
List findAll();
// 添加点击数量(对象做法)
void like(Long id);
// 返回点击数量(对象做法)
Set> getWithScores();
// 添加点击数量(id 做法)
void likeId(Long id);
// 返回点击数量(id 做法)
Collection> getWithScoresId();
创建 NewsService 接口的实现类
@Service("newsService")
public class NewsServiceImpl implements NewsService {
// 引入NewsRepository接口
@Resource
private NewsRepository newsRepository;
// 引入springframework.data.redis.core 包下的 实体类 RedisTemplate
@Resource
private RedisTemplate redisTemplate;
// 查出所有
@Override
public List findAll() {
return this.newsRepository.findAll();
}
// 在redis中存入对象
@Override
public void like(Long id) {
ZSetOperations opsZ = this.redisTemplate.opsForZSet();
// 使用id查询所有
Optional optional = this.newsRepository.findById(id);
// 如果optional有值存在
if (optional.isPresent()) {
// 取出查出NewsEntity 点击增加多少
NewsEntity news = optional.get();
// 添加到redis 中 1,名字 2,对象 3每次
opsZ.incrementScore("news:like", news, 1);
}
}
// 返回 按照scores排序好的数据
@Override
public Set> getWithScores() {
ZSetOperations opsZ = this.redisTemplate.opsForZSet();
// 取出redis 中的按照scores排序好的数据 1,取出数据的名字 2,从0 开始 3,到第10 个结束
Set> set = opsZ.reverseRangeWithScores("news:like", 0, 10);
return set;
}
// 在redis中存入id
@Override
public void likeId(Long id) {
ZSetOperations opsZ = this.redisTemplate.opsForZSet();
opsZ.incrementScore("news:like:id", id, 1);
}
// 从redis中取出 存入的id 与Scores
@Override
public Collection> getWithScoresId() {
ZSetOperations opsZ = this.redisTemplate.opsForZSet();
// 取出存入id的集合
Set> tuple = opsZ.reverseRangeWithScores("news:like:id", 0, 10);
// 这个tuple里保存的关键信息是每个新闻的分数和新闻的id的顺序.
List items = new ArrayList<>();
for (ZSetOperations.TypedTuple
创建 RedisConfig 配置 存储 redis 时 存入对象的配置
package com.lanou3g.redisdemo.config;
import org.springframework.cache.annotation.EnableCaching;
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.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* 创建人: 武奇
* 创建事件: 2019/6/25
*/
@Configuration
public class RedisConfig {
// 配置key的序列化
@Bean
public RedisSerializer keySerializer() {
return new StringRedisSerializer();
}
// 配置value的序列化
@Bean
public RedisSerializer valueSerializer() {
// 当向Redis中存储一个对象时候,
// 会把对象转换为json数据存储到Redis中
return new GenericJackson2JsonRedisSerializer();
}
//
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(keySerializer());
redisTemplate.setHashKeySerializer(keySerializer());
// 如果不配置JSON的序列化, 还想保存对象,
// 那么前提是这个对象是可以被序列化的, 也就是说
// 对应的类必须是实现Serializable接口的
// 如果需要使用JSON的序列化, 被保存的对象,
// 必须得有默认的构造方法, 否则对象能被存上, 但是读不出来
redisTemplate.setValueSerializer(valueSerializer());
redisTemplate.setHashValueSerializer(valueSerializer());
return redisTemplate;
}
/*
*/
}
这样 模拟的微博热搜 就写完了
Redis缓存
需要在 application.yml 里配置(其实可以不配置,只要导包时 有导入redis 包 那么他会自动匹配可以不写)
#若是已经导入redis框架 可以不写 (下面一段)它默认就是redis
redis:
host: localhost
port: 6379
#选择缓存器是 谁的缓存(可不写 加入redis框架后默认是redis
#如不加redis框架也可以用缓存,会默认用simple
cache:
type: redis
在SpringBoot 项目开始创建时,自动创建的实体类中写 开始缓存的注解
package com.lanou3g.redisdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
//启用缓存
@EnableCaching
public class RedisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RedisDemoApplication.class, args);
}
}
在cotroller 层 中 做缓存
// @Cacheable 该方法支持缓存 cacheNames缓存的名字
@Cacheable(cacheNames = "cache:news")
// 在创建工程最初的被创建的实体类中开启缓存加上 @EnableCaching 注解
@RequestMapping("/{id}")
public NewsEntity getOne(@PathVariable Long id) {
return this.newsService.findById(id);
}
// 再缓存中真正的key 是由两部分组成的:
// 第一部分是缓存的名字,也cacheNames就是相应的值
// 第二部分是缓存的key, 也就是key的属性
//在做数据更新的时候需要缓存进行同步
// @CacheEvict删掉某个缓存
@CacheEvict(cacheNames = "cache:news",key = "#news.id")
@RequestMapping("/update")
public NewsEntity update(NewsEntity news) {
return this.newsService.update(news);
}
// 添加数据
// @CachePut 直接更新缓存
// key的参数是 返回值的id
@CachePut(cacheNames = "cache:news",key = "#result.id")
@RequestMapping("/save")
public NewsEntity save(NewsEntity news){
return NewsEntity.builder()
.id(10001L)
.build();
}
只要加上注解 redis 就会开始缓存
@Cacheable 该方法支持缓存
@CachePut 直接更新缓存
@CacheEvict删掉某个缓存
缓存相关的注解,不一定非写在controller层
写在service或Dao层都可以
根据实际需求灵活使用
service 层和以前一样 写