数据库表
代码实现
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)));*/
}