大家好,我是兔哥呀。我又来啦,这个SpringBoot日记本系统已经接近尾声了,目前已经完成的模块有日记本的增删改查,类型的增删改查,头像上传,还有个人中心。
最后一节呢,我们来做一个收尾工作哈。
目录
按日期查询
首页有一个分区是按照日期查询,就是自动统计你具体月份的日记数量。
现在还是假数据,我们来看看日记表。
跟日期有关的,有一个create_date
我们存入的格式为:2022-04-16 12:17:40
要转换成2022年04月16日
可以通过sql来转换,也可以通过java来转。我们就通过sql来转吧,尝试着写出如下sql
SELECT date_format(str_to_date(create_date,'%Y-%m-%d %H:%i:%s'),'%Y年%m月%d日') from tbl_syn_blog
目标实现,然后我们做一个分组。
SELECT
date_format(str_to_date(create_date,'%Y-%m-%d %H:%i:%s'),'%Y年%m月%d日') date,
count(1) total
FROM
tbl_syn_blog
GROUP BY
date
妥了,铁子们。
底层逻辑搞定,接下来就是实现代码落地。这种sql比较复杂,无法用MP的单表操作API,我们就弄一个xml文件,用最传统的方式来完成。
配置文件:
mybatis-plus:
mapper-locations: classpath:com/rabbit/diary/dao/*.xml
type-aliases-package: com.rabbit.diary.bean
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
xml配置的路径是 classpath:com/rabbit/diary/dao/*.xml
之前自动生成代码的时候,已经存在xml了。
我们复制一下,得到BlogMapper.xml
我们接收的数据格式为:
就两个字段,一个date,一个total。
用List,Map就行了,也可以自己写个Bean,我这边就懒得写了。
弄一个查询接口:
@Mapper
public interface BlogMapper extends BaseMapper<TblSynBlog> {
... ...
List<Map<String,String>> getBlogsStatistics(Long userId);
}
Service类:
@Service
public class BlogServiceImpl implements BlogService {
......
@Override
public List<Map<String, String>> getBlogsStatistics() {
return blogMapper.getBlogsStatistics(StpUtil.getLoginIdAsLong());
}
}
对应的BlogMapper.xml
<?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.rabbit.diary.dao.BlogMapper">
<select id="getBlogsStatistics" resultType="java.util.HashMap">
SELECT
date_format(str_to_date(create_date,'%Y-%m-%d %H:%i:%s'),'%Y年%m月%d日') date,
count(1) total
FROM
tbl_syn_blog
where user_id = #{userId}
GROUP BY date
</select>
</mapper>
修改PageController,添加这一块数据
@RequestMapping("/")
@SaCheckLogin
public ModelAndView index(@RequestParam(required=false) String blogType, ModelAndView mav){
mav.setViewName("index");
mav.addObject("blogType",blogType);
mav.addObject("statistics",blogService.getBlogsStatistics());
return mav;
}
Sider.jsp修改,把统计数据改成活的
<div class="layui-col-md12" style="margin-top: 2px;">
<div class="layui-card">
<div class="layui-card-header"><b><i class="layui-icon layui-icon-date" style="color: #000;"></i></b>按日期</div>
<div class="layui-card-body">
<ul class="tlist">
<c:forEach items="${statistics}" var="item">
<li> <a href="${basePath}/?date=${item.date}">${item.date}(${item.total})</a></li>
</c:forEach>
</ul>
</div>
</div>
</div>
这里之所以能用<c:forEach>,是因为在上面加了JSTL依赖。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
效果:
有人看到这里可能会问,上面的日记分类不是用vue来做了,怎么这边又要用JSTL了?
对此我的回答是:我乐意,你打我呀?
开个玩笑,这里我是为了给大家演示,这两种方式有啥区别?
现在我们离开首页,随便点一个比如写日记。
你会发现,日记分类有的,但是按日期就没了。
为什么呢?
这是因为日记分类是用vue做的,每次刷新页面就会发送异步请求,获取日记分类的数据再渲染出来。(异步的)
但是日期统计则是写在后台代码中一并返回的。(同步的)
所以,我们需要再所有用到sider.jsp的后台方法中,都加上这一段代码。到底哪种方式好,是分场景的,这个场景,肯定是异步的好。
接下来,我们看下日期统计的url
${basePath}/?date=${item.date}
嗯哼?回到首页去了,那么我们也要用Controller做一个中转。
@RequestMapping("/")
@SaCheckLogin
public ModelAndView index(@RequestParam(required=false) String blogType,@RequestParam(required=false) String date, ModelAndView mav){
mav.setViewName("index");
mav.addObject("blogType",blogType);
mav.addObject("date",date);
mav.addObject("statistics",blogService.getBlogsStatistics());
return mav;
}
列表加载的时候,把date传过去。
后台接口是blog/select
我们发现接收的请求体用的是blog对象,没法接收date。
这边思路就有很多了,比如啊,你可以给Blog增加一个date属性。
也可以给这个方法增加一个新的参数。
我这边就直接加字段吧。
这边又有一个新的问题了,因为我们是用get方式来请求的,你送中文过来恐怕会有乱码。
所以,我们不妨改一下sql
<?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.rabbit.diary.dao.BlogMapper">
<select id="getBlogsStatistics" resultType="java.util.HashMap">
SELECT
date_format(str_to_date(create_date,'%Y-%m-%d %H:%i:%s'),'%Y年%m月%d日') date,
count(1) total,
date_format(str_to_date(create_date,'%Y-%m-%d %H:%i:%s'),'%Y-%m-%d')date2
FROM
tbl_syn_blog
where user_id = #{userId}
GROUP BY date
</select>
</mapper>
前端也要改
<li> <a href="${basePath}/?date=${item.date2}">${item.date}(${item.total})</a></li>
送过去的就是yyyy-MM-dd格式啦,避免了中文乱码的问题。
修改后的查询代码:
public Page<TblSynBlog> selectPage(Page<TblSynBlog> pageBean, TblSynBlog blog) {
QueryWrapper<TblSynBlog> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("update_date");
//只允许查看自己发布的日记
queryWrapper.eq("user_id", StpUtil.getLoginId());
queryWrapper.eq("is_delete", "0");
if(StrUtil.isNotEmpty(blog.getBlogType())){
queryWrapper.eq("blog_type",blog.getBlogType());
}
//按照具体日期来查
if(StrUtil.isNotEmpty(blog.getDate())){
queryWrapper.eq("date_format(str_to_date(create_date,'%Y-%m-%d %H:%i:%s'),'%Y-%m-%d')",blog.getDate());
}
return blogMapper.selectPage(pageBean,queryWrapper);
}
功能实现。
关键字搜索
最后一个功能,是关键字索引。
思路和日记分类搜索,还有按日期搜索差不了太多。
直接干。
<div class="searchbox layui-nav-item" style="width: 260px;height: 60px;">
<form method="post" action="${basePath}/">
<input style="display: inline-block;width: 60%" type="text" name="kws" required placeholder="请输入关键字" autocomplete="off" class="layui-input">
<button style="margin-top: -2px;" class="layui-btn layui-btn-primary"><i class="layui-icon layui-icon-search"></i>搜索</button>
</form>
</div>
走Controller
搞定。
PS:本章改了pom.xml,因为xml文件需要单独设置编译。
<!-- mapper.xml文件在java目录下 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
打包
打包成功,上线。
在线访问地址:http://diary.java18.cn/
肯定还有很多BUG,该版本进入内测阶段,有BUG欢迎告诉我哈。
项目一期到此结束,本项目视频教程后面我会抽时间录制的。
经过初步测试:百度APP打开会有样式错误,我用的小米手机,自带的浏览器就没事。PC端用谷歌浏览器比较好。