(一)工程建立到登录与认证-Spring boot、Shiro、Mybatis-Plus、MySql
(二)博客显示与登录后按钮按照Shiro授权显示加载html
(三)博客主页文章分页查询,预览显示
五、文章分页查询、预览显示
5.1 数据库
5.1.1 数据表设计
在第一章我们已经创建了数据库,并创建了几个用户相关的表,现在我们再来创建文章相关的数据表,sql语句如下
create table `article`(
`id` int(3) not null comment '博客id',
`title` varchar(100) not null comment '标题',
`text` longtext not null comment '正文',
`tag` varchar(255) not null comment '标签 java python',
`type` varchar(25) not null comment '文章类型 原创 转载',
`secret` int(1) not null default '0' comment '是否私密 0公开 1私密',
`create_time` date not null comment '创建时间',
`edit_time` date not null comment '最后编辑时间',
`likes` int(5) not null default '0' comment '点赞次数',
`author` varchar(20) not null comment '作者名称',
`digest` varchar(255) not null comment '摘要',
`watch` int(10) not null default '0' comment '浏览次数',
primary key (`id`)
) engine=InnoDB default charset=utf8mb4;
5.1.2 插入数据
insert into `article` values (0, '标题0', '正文0 如何使用java \n 正文', 'java', '原创', 0, '2021-01-13', '2022-01-10',0, 'liang', '摘要1...', 0);
insert into `article` values (1, '标题1', '正文1 如何使用python \n 正文', 'python', '原创', 0, '2021-02-11', '2022-02-10',0, 'liang', '摘要1...', 1);
insert into `article` values (2, '标题2', '正文2 如何使用Spring \n 正文', 'java, Spring', '原创', 0, '2022-01-10', '2022-02-10',0, 'liang', '摘要2...', 100);
insert into `article` values (3, '标题3', '正文3 如何使用linux \n 正文', 'linux', '转载', 0, '2021-10-10', '2022-01-10',0, 'liang', '摘要3...', 0);
insert into `article` values (4, '标题4', '正文4 如何使用c \n 正文', 'c', '原创', 1, '2022-10-10', '2022-01-10',0, 'liang', '摘要4...', 1);
insert into `article` values (5, '标题5', '正文5 如何使用c++ \n 正文', 'c++', '原创', 0, '2022-09-10', '2022-01-10',0, 'liang', '摘要5...', 0);
insert into `article` values (6, '标题6', '正文6 如何使用go \n 正文', 'go', '原创', 0, '2022-08-10', '2022-01-10',0, 'liang', '摘要6...', 122);
5.1.3 查询结果测试
select * from article;
5.2 实体类及Dao
5.2.1 实体类创建
-
创建
com.liang.modules.sys.entity.ArticleEntity
@Data @ToString @TableName("article") public class ArticleEntity implements Serializable { private static final long serialVersionUID = -3614720428468967910L; @TableId("id") private int id; private String title; //标题 private String text; //正文 private String tag; //标签 java python private String type; //文章类型 原创 转载 private int secret; // 0-公开 1-私密 private String createTime; private String editTime; private int likes; //赞数量 private String author; //作者 private String digest; //摘要 private int watch; //看过数 }
-
创建
com.liang.modules.sys.entity.VO.ArticleVOEntity
@Data @ToString(callSuper = true) @TableName("article") public class ArticleVOEntity extends ArticleEntity implements Serializable { private static final long serialVersionUID = -4837335904568195683L; @TableField(exist = false) private String[] tagValues; // 标签数组 @TableField(exist = false) private String articleUrl; //文章地址 }
5.2.2 创建ArticleDao
- 创建
com.liang.modules.sys.dao.ArticleDao
,继承BaseMapper(MyBatis-plus中特有的)@Repository public interface ArticleDao extends BaseMapper<ArticleVOEntity> { }
5.2.3 测试dao
- 在测试类
com.liang.TestBlog01ApplicationTests
中,这个类在之前的测试中也用过
类中创建内容如下@Autowired private ArticleDao articleDao; @Test void testArticleDao(){ List<ArticleVOEntity> articleVOEntities = articleDao.selectList(null); System.out.println(articleVOEntities); }
- 测试,点击
testArticleDao
左侧的绿色启动键,进行测试, 结果如红框内所示即成功了(可忽略内容不一致,因为当时测试的时候表内容不一样)
5.3 Service及Controller
5.3.1 两个工具类编写
- 页面返回结果工具类
创建com.liang.common.utils.PageResult
,内容如下@Data @ToString public class PageResult { private int pageNumber; //当前页数 private int totalPage; //总页数 private int records; //总记录数 private List<?> rows; //显示的行内容 ?是内容的类 }
- 字符串和数组转换工具类
创建com.liang.common.utils.StringAndArray
public class StringAndArray { /** * @method string转数组 * @description 将字符串转为数组,例如字符串为 “python, java” 将得到["python","java"] */ String[] stringToArray(String str){ String[] strings = str.split(","); for (int i = 0; i < strings.length; i++) { strings[i] = strings[i].trim(); } return strings; } /** * @method 数组转字符串 * @description 例如["python","java"] 将得到“python, java” */ String arrayToString(String[] strings){ StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < strings.length; i++) { stringBuilder.append(strings[i].trim()); if (i!=strings.length-1) stringBuilder.append(','); } return stringBuilder.toString(); } }
5.3.2 Mybatis-plus配置分页插件
创建com.liang.common.config.MybatisPlusConfig
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
5.3.3 创建ArticleService
- 创建
com.liang.modules.sys.service.ArticleService
public interface ArticleService { PageResult findAllArticle(int pageNumber, int pageSize); }
- 创建
com.liang.modules.sys.service.impl.ArticleServiceImpl
@Service public class ArticleServiceImpl implements ArticleService { @Autowired private ArticleDao articleDao; @Override public PageResult findAllArticle(int pageNumber, int pageSize) { PageResult pageResult = new PageResult(); QueryWrapper<ArticleVOEntity> wrapper = new QueryWrapper<>(); Page<ArticleVOEntity> page = new Page<>(pageNumber, pageSize); IPage<ArticleVOEntity> articles = articleDao.selectPage(page, wrapper.orderByDesc("create_time")); for (ArticleVOEntity article : articles.getRecords()) { article.setTagValues(StringAndArray.stringToArray(article.getTag())); article.setArticleUrl("/article/"+ article.getId()); } pageResult.setPageNumber(pageNumber); pageResult.setTotalPage((int) articles.getPages()); pageResult.setRecords((int) articles.getTotal()); pageResult.setRows(articles.getRecords()); return pageResult; } }
5.3.4 测试Service
- 编写并执行如下
@Autowired private ArticleService articleService; @Test void testArticleService(){ PageResult allArticle = articleService.findAllArticle(1, 5); System.out.println(allArticle); }
- 结果
5.3.5 创建ArticleController
-
@RestController public class ArticleController { @Autowired private ArticleService articleService; @GetMapping("/myArticles") public JsonResult myArticles(int pageSize, int pageNumber){ PageResult allArticle = articleService.findAllArticle(pageNumber, pageSize); return new JsonResult(200, "ok", allArticle); } }
5.3.6 测试Controller
- 运行整个Spring boot项目,地址栏输入
http://localhost:8080/myArticles?pageSize=5&pageNumber=1
- 结果
5.4 页面显示和加载
5.4.1 引入layui
原layui官网不知为何关闭了,可从layzui镜像网站下载,下载后将里面的layui
文件夹放置在src/main/resources/static
中
5.4.2 编写index.js
- 创建
static/style/js/index.js
文件,编写内容如下,实现首次页面加载时博客的显示,即显示第一页内容,并且每页显示数量为5/** * 本页博文显示 */ function putInArticle(data) { $(".qz-session-center").empty(); var articles = $(".qz-session-center"); $.each(data, function (index, article) { var center = $( '<div class="qz-center">' + '<header class="qz-article">' + '<h1 itemprop="name">' + '<a class="qz-article-title" href="' + article['articleUrl'] + '">' + article['title'] + '</a>' + '</h1>' + '<div class="qz-tt">' + '<span class="am-badge am-badge-success qz-mark">' + article['type'] + '</span> ' + '<span class=""><span class="am-icon-calendar"></span> ' + article['createTime'] + '</span> ' + '<span style="font-size: 14px;"><i class="am-icon-user"> ' + article['author'] + '</i></span> ' + '</div>' + '</header>' + '<div class="article-entry" style="height: 130px;overflow:hidden;">' + ' <p>' + article['digest'] + '</p>' + '</div>' + '<div class="read-all">' + '<a href="' + article['articleUrl'] + '">阅读全文 <i class="am-icon-angle-double-right"></i></a>' + '</div>' + '<hr>' + '<div class="article-tags">' + '</div>' + '</div>'); articles.append(center); for (var i = 0; i < article['tagValues'].length; i++) { var articleTag = $('<i class="am-icon-tag"><a class="tag aa" href="/tags?tag=' + article['tagValues'][i] + '"> ' + article['tagValues'][i] + ' </a></i>'); $('.article-tags').eq(index).append(articleTag); } }) } /** * 博客分页查询并显示 */ function pageRender(currentPage) { var jsonStr = {pageSize: 5,pageNumber: currentPage}; $.ajax({ type: "GET", url: "/myArticles", dataType: "json", data: jsonStr, success: function (data) { //放入数据 putInArticle(data.data.rows); } }) } // 加载页面时运行一次 pageRender(1);
- 编写到这里,就可以运行spring boot项目,并进入
http://localhost:8080/
查看页面,可以看到页面将会显示五个博客文章
4. 完善,编写页面选择以及翻页按钮显示
在index.js中添加一个函数,该函数用layui渲染翻页按钮,并实现翻页调用/** * 分页按钮显示 */ function putPageHelper(data, curnum) { var count = data.data.records; //总页数大于页码总数 layui.use('laypage', function () { var laypage = layui.laypage; //执行一个laypage实例 laypage.render({ elem: 'page-helper' , count: count//数据总数 , limit: 5 , curr: curnum , jump: function (obj, first) { if (!first) { curnum = obj.curr; pageRender(curnum); } } }); }); }
- 在
pageRender
函数中调用,并且调用scrollTo(0,0)
实现翻页后,页面转至最顶部,即将pageRender
完善为/** * 博客分页查询并显示 */ function pageRender(currentPage) { var jsonStr = {pageSize: 5,pageNumber: currentPage}; $.ajax({ type: "GET", url: "/myArticles", dataType: "json", data: jsonStr, success: function (data) { //放入数据 putInArticle(data.data.rows); //显示翻页按钮和翻页调用 putPageHelper(data, currentPage); scrollTo(0,0); } }) }
- 运行并测试,往下翻将显示翻页按钮
5.4 个人信息及文章统计显示
5.4.1 引入aside.html页面
- 引入templates/aside.html
- 将index.html中的
<div th:replace="aside :: aside"></div>
解注释 - 将csdn图标、qq二维码、微信二维码保存至
style/images/
中
- 运行项目(报错则检查target中是否有生成aside.html,没有则删除target重新运行),可以看到项目右侧将显示一些个人信息,但qq和微信二维码默认显示的,我们要做的效果是默认不显示,当鼠标移动到qq、微信图标时再显示,接下来将编写header.js来实现
5.4.2 编写header.js
创建static/style/js/header.js
文件,编写内容如下
$("#wx_picture").hide();
$("#qq_picture").hide();
$(".wxchat").mouseenter(function (){
$("#wx_picture").show();
});
$(".wxchat").mouseleave(function (){
$("#wx_picture").hide();
});
$(".qq").mouseenter(function (){
$("#qq_picture").show();
});
$(".qq").mouseleave(function (){
$("#qq_picture").hide();
});
这样就实现了鼠标移入移出qq、微信图标的二维码显示与隐藏
5.4.3 实现文章总数
未完待续