网站可以用ai做吗,wordpress商品模板,中国商标网商标查询官网查询,泰州公司网站建设#x1f34a; 编程有易不绕弯#xff0c;成长之路不孤单#xff01; 大家好#xff0c;我是熊哈哈#xff0c;这个项目从我接手到现在有了两个多月的时间了吧#xff0c;其实本来我在七月初就做完的吧#xff0c;但是六月份的时候生病了#xff0c;在家里休息了一个月的… 编程有易不绕弯成长之路不孤单 大家好我是熊哈哈这个项目从我接手到现在有了两个多月的时间了吧其实本来我在七月初就做完的吧但是六月份的时候生病了在家里休息了一个月的时间后来回到学校考试考完试之后就出来实习了这个项目也就一直拖了下去最近时间够了就在努力的去完成这个项目。 总体来说这个项目不是很难有很多的东西不够细节处理的也不是很到位请大家谅解一下。在我考虑到的不充分的地方一个就是在删除电子书的时候并没有删除电子书对应存在数据库当中的文章还有就是在登录的时候密码加密应该在前端就开始加密了不应该传到后端在进行加密处理其实还有很多不到位的地方需要大家去查找我在提示一下有没有考虑到为接口添加事物 此外项目还可以有改进部分一个是添加AOP做日志管理还有自定义异常类这些都是很重要的模块在实际的开发当中一定不要像代码当中的那么随意。其他的我还没有想到不过我记得我之前说过这个项目的权限校验不太合理有兴趣的可以了解一下RBAC还有SpringSecurity。 目录 编程有易不绕弯成长之路不孤单 一、今日目标
二、SpringBoot代码修改
2.1 新增IpUtil
2.2 添加访问量统计功能
2.3 新增点赞功能
2.4 实现数据统计
2.4.1 定时更新ebook数据
2.4.2 定时更新ebook_snapshot
2.5 展示总浏览量和30天内的数据变化 一、今日目标 上篇文章链接【wiki知识库】08.添加用户登录功能--后端SpringBoot部分-CSDN博客 上篇文章做了登录功能的后端逻辑实现了登录拦截还有权限校验部分为网站提供了一定的安全性保障在这篇文章就要实现最后的部分浏览量的统计和点赞功能。 这一部分就是纯Sql还有自动化任务。 二、SpringBoot代码修改 2.1 新增IpUtil 这个工具类的作用就是在你访问接口的时候可以获取到你的真实IP。 public class IpUtil {private static final String UNKNOWN unknown;private static final String LOCALHOST 127.0.0.1;private static final String SEPARATOR ,;public static String getIpAddr(HttpServletRequest request) {System.out.println(request);String ipAddress;try {ipAddress request.getHeader(x-forwarded-for);if (ipAddress null || ipAddress.length() 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {ipAddress request.getHeader(Proxy-Client-IP);}if (ipAddress null || ipAddress.length() 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {ipAddress request.getHeader(WL-Proxy-Client-IP);}if (ipAddress null || ipAddress.length() 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {ipAddress request.getRemoteAddr();if (LOCALHOST.equals(ipAddress)) {InetAddress inet null;try {inet InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress inet.getHostAddress();}}// 对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照,分割// ***.***.***.***.length()if (ipAddress ! null ipAddress.length() 15) {if (ipAddress.indexOf(SEPARATOR) 0) {ipAddress ipAddress.substring(0, ipAddress.indexOf(,));}}} catch (Exception e) {ipAddress ;}return ipAddress;}
}2.2 添加访问量统计功能 这个功能一说出来你知道要在哪里添加吗就是我们之前写过的fint-content接口当我们点开一篇文章查看的时候对应的我们要为这一篇文章增加访问量。 找打这个接口然后修改代码。 /*** 查找某个doc的content内容* param id content的id* return*/GetMapping(/find-content/{id})public CommonResp findContent(PathVariable Long id) {Content content contentService.getById(id);// 查找的同时更新阅读数docService.increaseViewCount(id);String message content.getContent();return new CommonResp(true,查找成功,message);} 这是在DocServiceImpl中添加的代码很简单压力给到mapper。 public void increaseViewCount(Long id) {docMapper.increaseViewCount(id);} 走带mapper中就是要执行我们自己写的sql语句在这之前大家先来考虑一个问题为了增加浏览量我这里给大家两种方案。 通过文档的id查询出文档的信息然后修改文档的浏览量然后在存回去。通过文档的id直接找到对应的数据然后直接修改浏览量。 不用想也是第二种。但是一定要注意如果要执行自定义的Sql一定要把xml文件放到resources目录下的mapper中。 update idincreaseViewCountupdate doc set view_count view_count 1 where id #{id}
/update 2.3 新增点赞功能 这个功能还是在DocController中添加的。 对应的接口代码如下。 /*** 给文章点赞* param id 传入的doc的id* return*/GetMapping(/vote/{id})public CommonResp vote(PathVariable Long id) {docService.increaseVoteCount(id);return new CommonResp(true,点赞成功,null);} DocServiceImpl中新增代码。这段代码中获取了HttpServletRequest对象通过这个对象我们就可以拿到用户访问时的IP为什么需要用户的IP 你有没有经历过这种情况当你访问某一篇博客的时候或者看一个视频的时候在你点赞了之后你就不能够在点赞了或者你在点赞就是取消点赞了我们这里解析用户IP也是一样的道理我们要把当前点赞用户的IP存放在Redis当中当用户点过一次之后我们就设置24小时内不能够在点赞。为什么一定要IP呢因为网站用户不需要账号登陆。 现在你知道了IpUtil的作用了吗。 public void increaseVoteCount(Long id) {ServletRequestAttributes attributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request attributes.getRequest();// 通过IPUtil获取远程访问的IPString ip IpUtil.getIpAddr(request);// 判断用户是否已经投票if (redisUtil.validateRepeat(DOC_VOTE_ id _ ip, 60 * 60 * 24)) {docMapper.increaseVoteCount(id);} else {throw new RuntimeException(您今日已经投过票了);}docMapper.increaseVoteCount(id);} 2.4 实现数据统计 想一下如果这个功能让你来实现你会从哪里入手 先来看看我们的数据库的表格吧。我们点开doc、ebook后都能看到有浏览量的统计但不同的是doc记录的是每一篇文档的浏览量而ebook记录的是某个电子书的浏览量至于下边的ebook_snapshot意味着每一日的电子书快照什么意思呢就是每一天当中每一本电子书的总浏览量和今日增长的浏览量。 再回想我们的代码我们只有在代码中添加了有关doc的浏览量统计那我们改如何同步三个表格呢 想想看doc统计的是文档的浏览量文档是带有ebook的id的我们只要把某个ebook下的doc做一个统计就好了这样就可以的到ebook中的浏览量数据了。 那么ebook_snapshot中的数据呢就像是下边的图所示。 view_count是电子书访问的总浏览量这个我们在ebook当中就已经有了至于vote_count和view_count同理。 那么view_increase呢这个数据记录着今日访问量。 我给大家标注了一下现在不难猜了吧今日的当前总访问量和昨天截止的访问量相减就是今日访问量了。 好了知道了这些就会让你更容易地理解Sql怎么写。 2.4.1 定时更新ebook数据 这是一个自动化任务过一段时间ebook中的数据就要和doc中的数据进行同步。 Component
public class EbookInfoTask {private static final Logger LOG LoggerFactory.getLogger(EbookInfoTask.class);Resourceprivate DocService docService;Resourceprivate SnowFlake snowFlake;/*** 每30秒更新电子书信息*/Scheduled(cron 5/30 * * * * ?)public void cron() {// 增加日志流水号MDC.put(LOG_ID, String.valueOf(snowFlake.nextId()));LOG.info(更新电子书下的文档数据开始);long start System.currentTimeMillis();docService.updateEbookInfo();LOG.info(更新电子书下的文档数据结束耗时{}毫秒, System.currentTimeMillis() - start);}
}service中的代码如下这个就好理解了。 update idupdateEbookInfoupdate ebook t1, (select ebook_id, count(1) doc_count, sum(view_count) view_count, sum(vote_count) vote_countfrom doc group by ebook_id) t2set t1.doc_count t2.doc_count, t1.view_count t2.view_count, t1.vote_count t2.vote_countwhere t1.id t2.ebook_id/update 2.4.2 定时更新ebook_snapshot Component
public class EbookSnapshotTask {private static final Logger LOG LoggerFactory.getLogger(EbookSnapshotTask.class);Resourceprivate EbookSnapshotService ebookSnapshotService;Resourceprivate SnowFlake snowFlake;/*** 自定义cron表达式跑批* 只有等上一次执行完成下一次才会在下一个时间点执行错过就错过*/Scheduled(cron 0 0/1 * * * ?)public void doSnapshot() {// 增加日志流水号MDC.put(LOG_ID, String.valueOf(snowFlake.nextId()));LOG.info(生成今日电子书快照开始);Long start System.currentTimeMillis();ebookSnapshotService.genSnapshot();LOG.info(生成今日电子书快照结束耗时{}毫秒, System.currentTimeMillis() - start);}
} 下边直接给出大家sql语句。 update idgenSnapshotINSERT INTO ebook_snapshot(ebook_id, date, view_count, vote_count, view_increase, vote_increase)SELECT t1.id, CURDATE(), 0, 0, 0, 0FROM ebook t1WHERE NOT EXISTS (SELECT 1FROM ebook_snapshot t2WHERE t1.id t2.ebook_idAND t2.date CURDATE());UPDATE ebook_snapshot t1JOIN ebook t2 ON t1.ebook_id t2.idSET t1.view_count t2.view_count,t1.vote_count t2.vote_countWHERE t1.date CURDATE();UPDATE ebook_snapshot t1LEFT JOIN (SELECT ebook_id, view_count, vote_countFROM ebook_snapshotWHERE date DATE_SUB(CURDATE(), INTERVAL 1 DAY)) t2 ON t1.ebook_id t2.ebook_idSET 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 不过你也别被吓到这个update中一共有三个sql现在来一条一条分析。 这是一条插入语句目的是什么呢先看where语句这是一个带有条件的插入sql当我们从ebook_snapshot中查找数据时如果没有发现日期是今天并且存在于ebook中的数据时候就会执行说白了就是看一下在当天有没有往这个表格中插入ebook的统计信息没有的话就插进去。 INSERT INTO ebook_snapshot(ebook_id, date, view_count, vote_count, view_increase, vote_increase)SELECT t1.id, CURDATE(), 0, 0, 0, 0FROM ebook t1WHERE NOT EXISTS (SELECT 1FROM ebook_snapshot t2WHERE t1.id t2.ebook_idAND t2.date CURDATE()); 再来看下一条这是一条更新语句更新的是表格当中的电子书总浏览量和总点赞量注意是当天的数据。 UPDATE ebook_snapshot t1JOIN ebook t2 ON t1.ebook_id t2.idSET t1.view_count t2.view_count,t1.vote_count t2.vote_countWHERE t1.date CURDATE(); 来看最后一条还是更新语句只不过更新的是当天的每个电子书的当日访问量和点赞量。 两张ebook_snapshot表格做连接拿到一张表格中今天所有电子书的数据还有昨天所有电子书的数据然后更新今天所有电子书的view_increase和vote_increase数值就是前边说的相减。 UPDATE ebook_snapshot t1LEFT JOIN (SELECT ebook_id, view_count, vote_countFROM ebook_snapshotWHERE date DATE_SUB(CURDATE(), INTERVAL 1 DAY)) t2 ON t1.ebook_id t2.ebook_idSET 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(); 2.5 展示总浏览量和30天内的数据变化 RestController
RequestMapping(/ebook-snapshot)
public class EbookSnapshotController {Resourceprivate EbookSnapshotService ebookSnapshotService;GetMapping(/get-statistic)public CommonResp getStatistic() {ListStatisticVo statisticResp ebookSnapshotService.getStatistic();return new CommonResp(true,success,statisticResp);}GetMapping(/get-30-statistic)public CommonResp get30Statistic() {ListStatisticVo statisticResp ebookSnapshotService.get30Statistic();return new CommonResp(true,success,statisticResp);}
} 话不多说我们直接上sql因为代码里直接一路调到mapper了。 这个是统计总浏览量和总点赞量的我这里统计多了其实直接让date等于curdate()就可以了。 select idgetStatistic resultTypecom.my.hawiki.vo.StatisticVoselectt1.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 voteIncreasefromebook_snapshot t1wheret1.date date_sub(curdate(), interval 1 day)group byt1.dateorder byt1.date desc;/select 这个呢就是统计三十日内的数据信息统计的是每一天的浏览量和点赞数但是不包括当日。 select idget30Statistic resultTypecom.my.hawiki.vo.StatisticVoselectt1.date as date,sum(t1.view_increase) as viewIncrease,sum(t1.vote_increase) as voteIncreasefromebook_snapshot t1wheret1.date between date_sub(curdate(), interval 30 day) and date_sub(curdate(), interval 1 day)group byt1.dateorder byt1.date asc;/select 到了这里也就结束了如果在代码上有问题或者想要获取源码的同学们可以私信联系我或者联系易编橙。 易编橙·终身成长社群相遇已是上上签-CSDN博客 文章底部有链接