...
 
Commits (3)
    https://gitcode.net/qq_45668004/fairy-wiki/-/commit/dcb5dd09ee172dfe19c4706ee00ad6bcaac918ac 11-3 根据电子书快照表生成相应的持久层代码 2021-04-30T15:14:02+08:00 yubinCloud yubin_SkyWalker@yeah.net https://gitcode.net/qq_45668004/fairy-wiki/-/commit/14a5175f1d19140be35ac4240cd338db07b0cdbe 11-5 增加定时任务,定时从ebook收集数据生成ebook_snapshot数据 2021-04-30T15:34:14+08:00 yubinCloud yubin_SkyWalker@yeah.net https://gitcode.net/qq_45668004/fairy-wiki/-/commit/c4cce942213fbafd43ae66d714b9df7ab08a4e02 11-6 后端增加获取统计数值的接口 2021-04-30T15:51:08+08:00 yubinCloud yubin_SkyWalker@yeah.net
package io.github.yubincloud.fairywiki.controller;
import io.github.yubincloud.fairywiki.dto.resp.ErrorCode;
import io.github.yubincloud.fairywiki.dto.resp.RestfulModel;
import io.github.yubincloud.fairywiki.dto.resp.StatisticRespDto;
import io.github.yubincloud.fairywiki.service.EbookSnapshotService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/ebook-snapshot")
@Api("电子书快照管理")
public class EbookSnapshotController {
@Resource
private EbookSnapshotService ebookSnapshotService;
@GetMapping("/get-statistic")
@ApiOperation(value = "从电子书快照中获取统计数据")
public RestfulModel<List<StatisticRespDto>> getStatistic() {
List<StatisticRespDto> statisticRespDtoList = ebookSnapshotService.getStatistic();
return new RestfulModel<>(ErrorCode.SUCCESS, "", statisticRespDtoList);
}
}
package io.github.yubincloud.fairywiki.domain;
import java.util.Date;
public class EbookSnapshot {
private Long id;
private Long ebookId;
private Date date;
private Integer viewCount;
private Integer voteCount;
private Integer viewIncrease;
private Integer voteIncrease;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getEbookId() {
return ebookId;
}
public void setEbookId(Long ebookId) {
this.ebookId = ebookId;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Integer getViewCount() {
return viewCount;
}
public void setViewCount(Integer viewCount) {
this.viewCount = viewCount;
}
public Integer getVoteCount() {
return voteCount;
}
public void setVoteCount(Integer voteCount) {
this.voteCount = voteCount;
}
public Integer getViewIncrease() {
return viewIncrease;
}
public void setViewIncrease(Integer viewIncrease) {
this.viewIncrease = viewIncrease;
}
public Integer getVoteIncrease() {
return voteIncrease;
}
public void setVoteIncrease(Integer voteIncrease) {
this.voteIncrease = voteIncrease;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", ebookId=").append(ebookId);
sb.append(", date=").append(date);
sb.append(", viewCount=").append(viewCount);
sb.append(", voteCount=").append(voteCount);
sb.append(", viewIncrease=").append(viewIncrease);
sb.append(", voteIncrease=").append(voteIncrease);
sb.append("]");
return sb.toString();
}
}
\ No newline at end of file
package io.github.yubincloud.fairywiki.dto.resp;
import lombok.Data;
import java.util.Date;
@Data
public class StatisticRespDto {
private Date date;
private int viewCount;
private int voteCount;
private int viewIncrease;
private int voteIncrease;
}
package io.github.yubincloud.fairywiki.job;
import io.github.yubincloud.fairywiki.service.EbookSnapshotService;
import io.github.yubincloud.fairywiki.utils.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class EbookSnapshotJob {
private static final Logger LOG = LoggerFactory.getLogger(EbookSnapshotJob.class);
@Resource
private EbookSnapshotService ebookSnapshotService;
@Resource
private SnowFlake snowFlake;
/**
* 自定义cron表达式跑批
* 只有等上一次执行完成,下一次才会在下一个时间点执行,错过就错过
*/
@Scheduled(cron = "0/5 * * * * ?")
public void doSnapshot() {
// 增加日志流水号
MDC.put("LOG_ID", String.valueOf(snowFlake.nextId()));
LOG.info("生成今日电子书快照开始");
long start = System.currentTimeMillis();
ebookSnapshotService.genSnapshots();
LOG.info("生成今日电子书快照结束,耗时:{}毫秒", System.currentTimeMillis() - start);
}
}
package io.github.yubincloud.fairywiki.mapper;
import io.github.yubincloud.fairywiki.domain.EbookSnapshot;
import io.github.yubincloud.fairywiki.domain.EbookSnapshotExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface EbookSnapshotMapper {
long countByExample(EbookSnapshotExample example);
int deleteByExample(EbookSnapshotExample example);
int deleteByPrimaryKey(Long id);
int insert(EbookSnapshot record);
int insertSelective(EbookSnapshot record);
List<EbookSnapshot> selectByExample(EbookSnapshotExample example);
EbookSnapshot selectByPrimaryKey(Long id);
int updateByExampleSelective(@Param("record") EbookSnapshot record, @Param("example") EbookSnapshotExample example);
int updateByExample(@Param("record") EbookSnapshot record, @Param("example") EbookSnapshotExample example);
int updateByPrimaryKeySelective(EbookSnapshot record);
int updateByPrimaryKey(EbookSnapshot record);
}
\ No newline at end of file
package io.github.yubincloud.fairywiki.mapper;
import io.github.yubincloud.fairywiki.dto.resp.StatisticRespDto;
import java.util.List;
public interface EbookSnapshotMapperCustom {
void genSnapshot();
List<StatisticRespDto> getStatistic();
}
package io.github.yubincloud.fairywiki.service;
import io.github.yubincloud.fairywiki.dto.resp.StatisticRespDto;
import io.github.yubincloud.fairywiki.mapper.EbookSnapshotMapperCustom;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class EbookSnapshotService {
@Resource
private EbookSnapshotMapperCustom ebookSnapshotMapperCustom;
public void genSnapshots() {
ebookSnapshotMapperCustom.genSnapshot();
}
/**
* 获取首页数值数据:总阅读数、总点赞数、今日阅读数、今日点赞数、今日预计阅读数、今日预计阅读增长
*/
public List<StatisticRespDto> getStatistic() {
return ebookSnapshotMapperCustom.getStatistic();
}
}
......@@ -43,6 +43,6 @@
targetPackage="io.github.yubincloud.fairywiki.mapper"
type="XMLMAPPER"/>
<table tableName="user" domainObjectName="User"/>
<table tableName="ebook_snapshot"/>
</context>
</generatorConfiguration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.github.yubincloud.fairywiki.mapper.EbookSnapshotMapper">
<resultMap id="BaseResultMap" type="io.github.yubincloud.fairywiki.domain.EbookSnapshot">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="ebook_id" jdbcType="BIGINT" property="ebookId" />
<result column="date" jdbcType="DATE" property="date" />
<result column="view_count" jdbcType="INTEGER" property="viewCount" />
<result column="vote_count" jdbcType="INTEGER" property="voteCount" />
<result column="view_increase" jdbcType="INTEGER" property="viewIncrease" />
<result column="vote_increase" jdbcType="INTEGER" property="voteIncrease" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, ebook_id, `date`, view_count, vote_count, view_increase, vote_increase
</sql>
<select id="selectByExample" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshotExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from ebook_snapshot
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from ebook_snapshot
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from ebook_snapshot
where id = #{id,jdbcType=BIGINT}
</delete>
<delete id="deleteByExample" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshotExample">
delete from ebook_snapshot
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshot">
insert into ebook_snapshot (id, ebook_id, `date`,
view_count, vote_count, view_increase,
vote_increase)
values (#{id,jdbcType=BIGINT}, #{ebookId,jdbcType=BIGINT}, #{date,jdbcType=DATE},
#{viewCount,jdbcType=INTEGER}, #{voteCount,jdbcType=INTEGER}, #{viewIncrease,jdbcType=INTEGER},
#{voteIncrease,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshot">
insert into ebook_snapshot
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="ebookId != null">
ebook_id,
</if>
<if test="date != null">
`date`,
</if>
<if test="viewCount != null">
view_count,
</if>
<if test="voteCount != null">
vote_count,
</if>
<if test="viewIncrease != null">
view_increase,
</if>
<if test="voteIncrease != null">
vote_increase,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="ebookId != null">
#{ebookId,jdbcType=BIGINT},
</if>
<if test="date != null">
#{date,jdbcType=DATE},
</if>
<if test="viewCount != null">
#{viewCount,jdbcType=INTEGER},
</if>
<if test="voteCount != null">
#{voteCount,jdbcType=INTEGER},
</if>
<if test="viewIncrease != null">
#{viewIncrease,jdbcType=INTEGER},
</if>
<if test="voteIncrease != null">
#{voteIncrease,jdbcType=INTEGER},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshotExample" resultType="java.lang.Long">
select count(*) from ebook_snapshot
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update ebook_snapshot
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=BIGINT},
</if>
<if test="record.ebookId != null">
ebook_id = #{record.ebookId,jdbcType=BIGINT},
</if>
<if test="record.date != null">
`date` = #{record.date,jdbcType=DATE},
</if>
<if test="record.viewCount != null">
view_count = #{record.viewCount,jdbcType=INTEGER},
</if>
<if test="record.voteCount != null">
vote_count = #{record.voteCount,jdbcType=INTEGER},
</if>
<if test="record.viewIncrease != null">
view_increase = #{record.viewIncrease,jdbcType=INTEGER},
</if>
<if test="record.voteIncrease != null">
vote_increase = #{record.voteIncrease,jdbcType=INTEGER},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update ebook_snapshot
set id = #{record.id,jdbcType=BIGINT},
ebook_id = #{record.ebookId,jdbcType=BIGINT},
`date` = #{record.date,jdbcType=DATE},
view_count = #{record.viewCount,jdbcType=INTEGER},
vote_count = #{record.voteCount,jdbcType=INTEGER},
view_increase = #{record.viewIncrease,jdbcType=INTEGER},
vote_increase = #{record.voteIncrease,jdbcType=INTEGER}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshot">
update ebook_snapshot
<set>
<if test="ebookId != null">
ebook_id = #{ebookId,jdbcType=BIGINT},
</if>
<if test="date != null">
`date` = #{date,jdbcType=DATE},
</if>
<if test="viewCount != null">
view_count = #{viewCount,jdbcType=INTEGER},
</if>
<if test="voteCount != null">
vote_count = #{voteCount,jdbcType=INTEGER},
</if>
<if test="viewIncrease != null">
view_increase = #{viewIncrease,jdbcType=INTEGER},
</if>
<if test="voteIncrease != null">
vote_increase = #{voteIncrease,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="io.github.yubincloud.fairywiki.domain.EbookSnapshot">
update ebook_snapshot
set ebook_id = #{ebookId,jdbcType=BIGINT},
`date` = #{date,jdbcType=DATE},
view_count = #{viewCount,jdbcType=INTEGER},
vote_count = #{voteCount,jdbcType=INTEGER},
view_increase = #{viewIncrease,jdbcType=INTEGER},
vote_increase = #{voteIncrease,jdbcType=INTEGER}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="io.github.yubincloud.fairywiki.mapper.EbookSnapshotMapperCustom" >
<!--
# 方案一(ID不连续):
# 删除今天的数据
# 为所有的电子书生成一条今天的记录
# 更新总阅读数、总点赞数
# 更新今日阅读数、今日点赞数
# 方案二(ID连续):
# 为所有的电子书生成一条今天的记录,如果还没有
# 更新总阅读数、总点赞数
# 更新今日阅读数、今日点赞数
-->
<update id="genSnapshot">
INSERT INTO ebook_snapshot(ebook_id, `date`, view_count, vote_count, view_increase, vote_increase)
SELECT t1.id, curdate(), 0, 0, 0, 0
FROM ebook t1
WHERE NOT EXISTS(SELECT 1
FROM ebook_snapshot t2
WHERE t1.id = t2.ebook_id
AND t2.`date` = curdate());
UPDATE ebook_snapshot t1, ebook t2
SET t1.view_count = t2.view_count,
t1.vote_count = t2.vote_count
WHERE t1.`date` = curdate()
AND t1.ebook_id = t2.id;
UPDATE ebook_snapshot t1 LEFT JOIN (SELECT ebook_id, view_count, vote_count
FROM ebook_snapshot
WHERE `date` = date_sub(curdate(), INTERVAL 1 DAY)) t2
ON t1.ebook_id = t2.ebook_id
SET t1.view_increase = (t1.view_count - ifnull(t2.view_count, 0)),
t1.vote_increase = (t1.vote_count - ifnull(t2.vote_count, 0))
WHERE t1.`date` = curdate();
</update>
<select id="getStatistic" resultType="io.github.yubincloud.fairywiki.dto.resp.StatisticRespDto">
SELECT
t1.`date` AS `date`,
SUM(t1.view_count) AS viewCount,
SUM(t1.vote_count) AS voteCount,
SUM(t1.view_increase) AS viewIncrease,
SUM(t1.vote_increase) AS voteIncrease
FROM
ebook_snapshot t1
WHERE
t1.`date` >= date_sub(curdate(), INTERVAL 1 DAY)
GROUP BY
t1.`date`
ORDER BY
t1.`date` ASC;
</select>
</mapper>
\ No newline at end of file