Springboot implements redis to add cache to video playback rankings

Step 0: Create a simple database: db_video, and create a t_video table with four fields: id, name, author, video_view. as the picture shows:

Step 1: Add dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wei</groupId>
    <artifactId>qiangpiao</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>qiangpiao</name>
    <description>qiangpiao</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ibatis</groupId>
            <artifactId>ibatis-sqlmap</artifactId>
            <version>2.1.0.565</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Step 2: Configuration information

server.port=8080
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
ticket.total=12
spring.data.redis.password=
#数据库
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_video?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=

Step 3: Write the entity class: VideoPo

package com.wei.qiangpiao.pojo;

public class VideoPo {
    private Integer Id;
    private String name;
    private String author;
    private Integer videoView;

    public Integer getId() {
        return Id;
    }

    public void setId(Integer id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Integer getVideoView() {
        return videoView;
    }

    public void setVideoView(Integer videoView) {
        this.videoView = videoView;
    }
}

Step 4: Write the dao layer

package com.wei.qiangpiao.mapper;

import com.wei.qiangpiao.pojo.VideoPo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.Mapping;

import java.util.List;

@Mapper
public interface VideoMapper {
    @Select("select * from t_video order by video_view desc")
    @Results(@Result(property = "videoView", column = "video_view"))
    List<VideoPo> getRankKingList();
}

Step 5: Register the jedis object and write the redis operation service class RedisDaoImpl

package com.wei.qiangpiao.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 注册jedis对象
 */
@Configuration
public class JedisConfig {
    @Autowired
    Environment env;
//    //创建线程池
//    public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
//            10, 100, 10, TimeUnit.SECONDS,
//            new LinkedBlockingDeque<Runnable>()
//    );
//
//    @Bean
//    public Jedis getJedis() {
//
//        //jedis操作redis,连接配置信息,本地连接
//        Jedis jedis = new Jedis(env.getProperty("spring.data.redis.host"), Integer.parseInt(env.getProperty("spring.data.redis.port")));
//        //登录redis密码
//        jedis.auth("abc123456");
//    }

    @Bean
    public Jedis getJedis(){
        return new Jedis(new HostAndPort(
                env.getProperty("spring.data.redis.host"),
                env.getProperty("spring.data.redis.port", Integer.class)
        ),new JedisClientConfig(){
            public int getConnectionTimeoutMillis() {// 超时毫秒数
                return 2000;
            }

            public String getPassword() {// 密码默认为空
                return env.getProperty("spring.data.redis.password");
            }
        }
        );
    }
}
package com.wei.qiangpiao.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.*;
import com.wei.qiangpiao.pojo.VideoPo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
getRankingList()方法,读取保存在排行榜数据库的JSON字符串,
并将字符串转换为实体类list对象。
saveRankingList(List<VideoPo> list)方法将排行榜的数据解析成JSON字符串并保存在redis中
*/
@Service
public class RedisDaoImpl {
    @Autowired
    Jedis jedis;

    @Autowired
    ObjectMapper jackSon;      //jason解析器
    //读取保存在排行榜数据库的JSON字符串,并将字符串转换为实体类list对象
    public List<VideoPo> getRankingList(){
        String rankingList = jedis.get("rankingList");//读取缓存中的Jason
        if (rankingList == null) {
            return null;
        }
        ArrayList<VideoPo> videoPos = new ArrayList<>();
        try {
            //将Jason字符串解析成数组节点
            ArrayNode VideoNode =(ArrayNode) jackSon.readTree(rankingList);
            for (JsonNode node :
                    VideoNode) {
                //将每一个节点解析成实体类对象
                VideoPo videoPo = jackSon.convertValue(node, VideoPo.class);
                videoPos.add(videoPo);
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return videoPos;
    }

    //将排行榜的数据解析成JSON字符串并保存在redis中
    public void saveRankingList(List<VideoPo> list) throws JsonProcessingException {
        String listJson = jackSon.writeValueAsString(list);//解析成JSON字符串
        //JSON字符串放到缓存中,10秒后过期
        jedis.set("rankingList", listJson);
        jedis.expire("rankingList", 10);
    }
}

Step 6: Service layer

package com.wei.qiangpiao.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.wei.qiangpiao.mapper.VideoMapper;
import com.wei.qiangpiao.pojo.VideoPo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class VideoService {
    @Autowired
    RedisDaoImpl redisDao;
    @Autowired
    VideoMapper videoMapper;
    private static final Logger log = LoggerFactory.getLogger(VideoService.class);

    public List<VideoPo> getRankingList() throws JsonProcessingException {//获取排行榜
        List<VideoPo> list = redisDao.getRankingList();//先从Redis中取数据
        log.info("访问缓存");
        if (list == null) {
            list = videoMapper.getRankKingList();
            log.info("缓存中没有数据,则访问数据库");
            log.info("从数据库总取出来后,在缓存中也保存一份");
            redisDao.saveRankingList(list);
            return list;
        }
        return list;
    }
}

Step 7: Controller layer

package com.wei.qiangpiao.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.wei.qiangpiao.pojo.VideoPo;
import com.wei.qiangpiao.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Controller
public class VideoController {

    @Autowired
    VideoService videoService;

    @GetMapping("/rankingList")
    public String gerRankingList(Model model) throws JsonProcessingException {
        List<VideoPo> list = videoService.getRankingList();
        model.addAttribute("rankingList", list);
        return "videoViewList";

    }
}

Step 8: Front-end page layer: videoViewList.HTML

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>播放量排行榜</title>
  <style  type="text/css">
.table-tr{
    display:table-row;
}
.table-td{
    display: table-cell;
    width: 130px;
    text-align: center;
}
  </style>
</head>
<body>
<div class="table-tr">
  <div class="table-td">排名</div>
  <div class="table-td">播放量</div>
  <div class="table-td">视频名称</div>
  <div class="table-td">上传者</div>
</div>
<div th:each="video:${rankingList}" class="table-tr">
    <div class="table-td" th:text="${videoStat.index+1}"></div>
    <div class="table-td" th:text="${video.getVideoView()}"></div>
    <div class="table-td" th:text="${video.getName()}"></div>
    <div class="table-td" th:text="${video.getAuthor()}"></div>
</div>
</body>
</html>

Step 9: Display of running results

 

Guess you like

Origin blog.csdn.net/qq_35207086/article/details/128279686