redis实现文章点击量

数据库表

在这里插入图片描述

代码实现

domain

@TableName("t_articles_hits")
@Data
public class ArticlesHits implements Serializable {
    @TableId(type = IdType.INPUT)
    private Long id;
    private Long articleId;
    private Long hits;
    private Date createTime;
    private Date chageTime;
}

dao

@Repository
public interface ArticlesHitsDao extends BaseMapper<ArticlesHits> {

    /**
     * @param articlesHits 根据id查询
     * @return
     */
    ArticlesHits findHitsById(Long articlesHits);

    /**
     * @param id 根据文章id添加
     * @return
     */
    Long insertSelective( Long id);

    /**
     * @param views 根据id将缓存更新到数据库持久
     * @return
     */
    Long updateHitsId(ArticlesHits views);

    /**
     * @param articlesHits 设置并更新需要的参数
     * @return
     */
    int updateHits( ArticlesHits articlesHits);


}

Mapper

<?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="com.wwtx.chinesemedicine.service.dao.ArticlesHitsDao">

    <resultMap id="ArticlesHitsMap" type="com.wwtx.chinesemedicine.service.models.domain.ArticlesHits" >
        <id column="id" property="id"  />
        <result property="articleId" column="article_id"  />
        <result property="hits" column="hits" />
        <result property="createTime" column="create_time" />
        <result property="chageTime" column="chage_time" />
    </resultMap>

    <update id="updateHits" >
      update t_articles_hits set id=#{id},hits=#{hits},create_time=#{createTime},chage_time=#{chageTime}  where article_id=#{articleId}
    </update>
    <update id="updateHitsId" >
      update t_articles_hits set hits=#{hits}  where article_id=#{articleId}
    </update>
    <sql id="Base_Column_List" >
        id, article_id,hits,create_time,chage_time
    </sql>
    <insert id="insertSelective" parameterType="com.wwtx.chinesemedicine.service.models.domain.ArticlesHits">
        insert into t_articles_hits(id,article_id,chage_time,create_time) select id,article_id,create_time,change_time from t_articles WHERE article_id=#{record};
    </insert>

    <select id="findHitsById" resultType="com.wwtx.chinesemedicine.service.models.domain.ArticlesHits"  >
        select <include refid="Base_Column_List"/>
        from t_articles_hits where article_id = #{articleId}
    </select>
 <!--   <select id="findHitsById" resultType="com.wwtx.chinesemedicine.service.models.domain.ArticlesHits" >
        select * from t_articles_hits where article_id = #{articleId}
    </select>-->
    <select id="findArticlesById" resultType="com.wwtx.chinesemedicine.service.models.domain.Articles" parameterType="long">
        select * from t_articles t1 where article_id = #{articleId}
    </select>
    <update id="updateHits" parameterType="com.wwtx.chinesemedicine.service.models.domain.ArticlesHits">
        update t_articles_hits
        <trim prefix="set" suffixOverrides=",">
            <if test="articlesHits.hits != null and articlesHits.hits != '' ">
                hits = #{articlesHits.hits},
            </if>
        </trim>
        where articleId = #{articlesHits.articleId}
    </update>

</mapper>

Service

public interface ArticlesHitsService {

    /**
     * @param id 根据id查询缓存点击量
     * @return
     */
    Long findHitsById(Long id);

}

Impi

@Service
public class ArticlesHitsServiceImpl implements ArticlesHitsService {
    private static final Logger logger = LoggerFactory.getLogger(ArticlesHitsServiceImpl.class);
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ArticlesHitsDao hitsDao;
    @Autowired
    private IdWorkerUtil idWorkerUtil;
    @Autowired
    private ArticlesDao articlesDao;
    @Override
    public Long findHitsById(Long id) {
        logger.info("======================开始 同步文章访问量======================");
        Long startTime = System.nanoTime();
        String key = "hitsId" + id;
        boolean hasKey = redisUtil.hasKey(key);
        long num = 0;
        if (hasKey) {
            long start = System.currentTimeMillis();
            Long aLong = redisUtil.get(key, Long.class);
            num = redisUtil.incrBy(key,aLong);
            System.out.println(num);
            ArticlesHits hits = hitsDao.findHitsById(id);
            Long articles = articlesDao.selectById(id);
            try{
                if(num != 0 && num % 50 == 0){//redis中每满50次,做一次数据落地
                    Long h = redisUtil.get(key,Long.class);
                    hits.setHits(h);
                    hitsDao.updateHitsId(hits);
                    logger.info("更新数据库点击数量成功:"+num);
                }
            }catch(Exception e){
                logger.error("更新数据库点击数量异常", e);
            }
            Long h = redisUtil.get(key,Long.class);
            //根据文章id,查询有没有点击量记录
            System.out.println("==========从缓存中获得数据=========");
            System.out.println(h+"--------------------------------");
            System.out.println(articles.toString()+"-----------");
            System.out.println("==============================");
            long end = System.currentTimeMillis();
            System.out.println("查询redis花费的时间是:" + (end - start)+"s");
            return articles;
        } else {
            long start = System.currentTimeMillis();
            ArticlesHits hitsById = hitsDao.findHitsById(id);

            //数据库没数据,添加数据
            if (hitsById==null){
                hitsDao.insertSelective(id);
            }
                ArticlesHits hits = hitsDao.findHitsById(id);
            if (hits!=null){
                hits.setId(idWorkerUtil.nextId());
                hits.setChageTime(new Date());
                hits.setHits(hits.getHits()+1);
                hits.setCreateTime(new Date());
                hitsDao.updateHits(hits);
            }
            System.out.println("==========从数据表中获得数据=========");
            System.out.println(hits.getArticleId());
            System.out.println("==============================");
            Long hits1 = hits.getHits();
            Long articleId = hits.getArticleId();
            Long articles = articlesDao.selectById(id);
            Integer integer = Integer.valueOf(Math.toIntExact(hits1));
            // 写入缓存
            redisUtil.set(key, integer, (long) 5, TimeUnit.HOURS);
            long end = System.currentTimeMillis();
            System.out.println("查询mysql花费的时间是:" + (end - start)+"s");
            Long endTime = System.nanoTime();
            logger.info("本次文章访问量同步成功, 总耗时: {}", (endTime - startTime) / 1000000 + "ms");
            logger.info("======================结束 文章访问量结束======================");
            return articles;
        }

    }


}

controller

/**
 * 获取文章详情
 *
 * @param articlesId
 * @return
 */
@GetMapping("articles/{articlesId}")
@ApiOperation("获取文章详情")
public Long queryArticles(@NotNull @RequestParam @ApiParam("文章id") Long articlesId) {
    return articlesHitsService.findHitsById(articlesId);
    /*return articlesService.selectArticles(Long.valueOf(String.valueOf(hitsById)));*/
}
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值