实现功能

SSM框架实战-搭建自己的个人博客4-文章管理与展示_数据

主要实现上图所示的功能,从数据库中查询到所有文章数据,并进行显示如标题,栏目等信息,可以通过分类查询文章,通过标签查询文章,也可以通过搜索进行模糊查询,或者三者进行联合查询,通过操作按钮改变文章的状态。通过新增按钮调转至新增页面,如果没有登录会先跳转至登录界面。 

ArticleController

//后台的主页面
@RequestMapping("/back")
public String back(Model model) {

//类别列表
List <Category> categories = categoryService.selectAllCategory();

//标签列表
List <Tag> tags = tagService.selectAllTag();

model.addAttribute("categoryList", categories);
model.addAttribute("tagList",tags);
return "article/article_list";
}

//后台的分页页面
@RequestMapping("/load")
public String load(Model model, Pager<Article> pager, String param) throws UnsupportedEncodingException {
System.out.println("参数:param:"+param+",pager:"+pager.toString());

Article article = JsonUtil.fromJson(param, Article.class);
if (article != null && article.getTitle() != null && "".equals(article.getTitle())) {
//标题参数不为空时,需要进行解码处理
String title = URLDecoder.decode(article.getTitle(), "utf-8");
article.setTitle(title);
}

//分页相关的
//需要获取当前条件下数据的个数
if (pager.getPage() == 1) {
// 当前条件下第一次查询
Integer articleCount = articleService.getArticleCount(article, pager);
System.out.println("符合条件:"+articleCount);
pager.setTotalCount(articleCount);
}

List <Article> articles = articleService.getArticlesByPage(article, pager);

model.addAttribute("articleList",articles);


return "article/article_pager";
}


@RequestMapping("/updateStatue")
@ResponseBody
public Result updateStatue(@Param("id") Integer id, @Param("status") Integer status) {
Article article = new Article();
article.setId(id);
article.setStatus(status);
if (articleService.updataStatus(article)) {
return new Result("success","成功");
} else {
return new Result("fail","修改失败");
}

}

Service层

//获取符合条件的数据数量
public Integer getArticleCount(Article article,Pager pager) {
HashMap<String, Object> hashMap = new HashMap <>();
hashMap.put("article", article);
Integer integer = articleMapper.selectCountByArticle(hashMap);
return integer;
}

//对符合条件的数据进行分页处理
public List<Article> getArticlesByPage(Article article,Pager pager) {
HashMap <String, Object> hashMap = new HashMap <>();
hashMap.put("article", article);
hashMap.put("start",pager.getStart());
hashMap.put("limit", pager.getLimit());

List <Article> articles = articleMapper.selectArticleByPager(hashMap);
return articles;
}


//修改状态
public boolean updataStatus(Article a) {
int i = articleMapper.updateStatus(a);
if (i> 0) {
return true;
} else {
return false;
}
}

Paper工具类

该工具类主要用于处理分页功能,

package com.tulun.util;

import java.util.ArrayList;
import java.util.List;

/**
* @功能:分页类
*
* 分页信息主要包括几个:当前页 每页显示数 总页数 总数量 和分页返回的信息
*
* @作者: gdz
* @时间: 2019-6-18 下午5:14:29
*/
public class Pager<T> {

/**
* 默认每页显示数
*/
public static final int PAGE_SIZE = 10;

/**
* 默认页数
*/
public static final int PAGE_NUM = 1;

/**
* 页数
*/
private int page;

/**
* 每页显示数
*/
private int limit = PAGE_SIZE;

/**
* 总页数
*/
private int totalPageNum;

/**
* 记录总数
*/
private int totalCount;

/**
* 分页信息
*/
private List<T> rows = new ArrayList<T>();

/**
* 分页计算起始值
*/
private int start;

/**
* 分页计算结束值 暂时没用
*/
private int endIndex;

public void setPageNum(int pageNum) {
if(pageNum <= 0){
pageNum = PAGE_NUM;
}
if(pageNum > totalPageNum){
pageNum = totalPageNum;
}
// 分页开始值 关键
if(pageNum == 0){
start = 0;
}else{
start = (pageNum - 1) * limit;
}
this.page = pageNum;
}

public int getStart() {
// 分页开始值 关键
if (page == 0) {
start = 0;
} else {
start = (page - 1) * limit;
}
return start;
}

public void setPageSize(int pageSize) {
if(pageSize <= 0){
pageSize = PAGE_SIZE;
}
// 计算最大页数
int pageCount = totalCount / pageSize;
if(totalCount % pageSize == 0){
totalPageNum = pageCount;
}else{
totalPageNum = pageCount + 1;
}
this.limit = pageSize;
}

public int getTotalPageNum() {
return totalPageNum;
}

public void setTotalPageNum(int totalPageNum) {
this.totalPageNum = totalPageNum;
}

public int getTotalCount() {
return totalCount;
}

public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
if(totalCount > 0){
if(page <= 0){
page = PAGE_NUM;
}
// 计算最大页数
int pageCount = totalCount / PAGE_SIZE;
if(totalCount % PAGE_SIZE == 0){
totalPageNum = pageCount;
}else{
totalPageNum = pageCount + 1;
}
}else{
totalPageNum = 0;
}

if(page > totalPageNum){
page = totalPageNum;
}
}

public List<T> getRows() {
return rows;
}

public void setRows(List<T> rows) {
this.rows = rows;
}

public int getEndIndex() {
return endIndex;
}

public void setEndIndex(int endIndex) {
this.endIndex = endIndex;
}

public int getPage() {
return page;
}

public void setPage(int page) {
this.page = page;
}

public int getLimit() {
return limit;
}

public void setLimit(int limit) {
this.limit = limit;
}

public void setStart(int start) {
this.start = start;
}

@Override
public String toString() {
return "Pager{" +
"page=" + page +
", limit=" + limit +
", totalPageNum=" + totalPageNum +
", totalCount=" + totalCount +
", rows=" + rows +
", start=" + start +
", endIndex=" + endIndex +
'}';
}
}

 ArticleMapper.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.tulun.dao.ArticleMapper">
<resultMap id="articleMap" type="com.tulun.model.Article">
<result column="id" property="id"></result>
<result column="categoryId" property="categoryId"></result>
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<result column="description" property="description"></result>
<result column="status" property="status"></result>
<result column="author" property="author"></result>
<result column="createTime" property="createTime"></result>
<result column="categoryName" property="categoryName"></result>
<result column="showCount" property="showCount"></result>
<result column="content" property="content" typeHandler="com.tulun.util.ConvertBlobTypeHandler"></result>
</resultMap>

<insert id="addArticle" parameterType="com.tulun.model.Article">
insert into t_article (categoryId,title,content,description,status,author,createTime)
values (#{categoryId},#{title},#{content},#{description},#{status},#{author},#{createTime})
</insert>

<select id="getArticleById" parameterType="int" resultMap="articleMap">
select a.*,c.categoryName categoryName from t_article a, t_category c where a.categoryId = c.id and a.id = #{id}
</select>

<select id="getAllArticle" resultMap="articleMap">
select a.*,c.categoryName categoryName from t_article a, t_category c where a.categoryId = c.id order by a.createTime desc
</select>

<select id="getAllArticleByCategoryId" resultMap="articleMap">
select a.*,c.categoryName categoryName from t_article a, t_category c where a.categoryId = c.id and a.categoryId = #{categoryId} order by a.createTime desc
</select>

<!--mybatis中的动态sql-->
<select id="selectCountByArticle" parameterType="map" resultType="int">
select count(*)
from t_article ta
join t_category tc
on ta.categoryId = tc.id
<where>
<if test="article.title != null">
and ta.title like concat('%', #{article.title}, '%')
</if>
<if test="article.categoryId != null and article.categoryId != 0">
and ta.categoryId = #{article.categoryId}
</if>
<if test="article.tagId != null and article.tagId != 0">
and exists (select 1 from t_article_tag tt where tt.articleId = ta.id and tt.tagId = #{article.tagId})
</if>
</where>
</select>

<select id="selectArticleByPager" parameterType="map" resultMap="articleMap">
select ta.id,ta.categoryId,tc.categoryName,ta.title,ta.content,ta.author,ta.createTime,DATE_FORMAT(ta.createTime,'%Y-%m-%d %H:%i:%s') as time,
ta.showCount,ta.status
from t_article ta
join t_category tc
on ta.categoryId = tc.id
<where>
<if test="article.title != null">
and ta.title like concat('%', #{article.title}, '%')
</if>
<if test="article.categoryId != null and article.categoryId != 0">
and ta.categoryId = #{article.categoryId}
</if>
<if test="article.tagId != null and article.tagId != 0">
and exists (select 1 from t_article_tag tt where tt.articleId = ta.id and tt.tagId = #{article.tagId})
</if>

</where>

order by ta.createTime desc
limit #{start},#{limit}

</select>

<update id="updateStatus" parameterType="com.tulun.model.Article">
update t_article set status =#{status} where id = #{id}
</update>
</mapper>

 前端页面

主要进行页面展示,包括ID,标题,状态,发表时间等等。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fm" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%
String path = request.getContextPath();
String basePath1 = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th>Id</th>
<th>标题</th>
<th>栏目</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<%--<div>--%>
<tbody>
<c:forEach items="${articleList}" var="article">
<tr class="gradeX">
<td>${article.id}</td>
<td>
<a target="_blank" href="<%=basePath%>article/${article.id}">
${article.title}
</a>
</td>
<td>
<a target="_blank" href="<%=basePath1%>/loadPage/${article.categoryId}" >
${article.categoryName}
</a>
</td>
<td>
<c:if test="${article.status == 0}">正常</c:if>
<c:if test="${article.status == 1}">不可用</c:if>
</td>
<td>${article.time}</td>
<td>
<c:if test="${article.status == 0}">
<button class="btn btn-info btn-xs" type="button"
title="关闭" onclick="updateStatue(${article.id},1)">关闭
</button>
</c:if>
<c:if test="${article.status == 1}">
<button class="btn btn-info btn-xs" type="button"
title="开启" onclick="updateStatue(${article.id},0)">开启
</button>
</c:if>

</td>
</tr>
</c:forEach>
</tbody>
</table>


<jsp:include page="pager.jsp" flush="true"></jsp:include>

该jsp内嵌在上一个jsp中,用于进行分页操作。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fm" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>


<c:if test="${pager.totalCount gt 0 and pager.totalPageNum gt 1}">
<div id="pager" class="row">
<input type="hidden" id="page" name="page" value="${pager.page}"/>
<div class="col-sm-6">
<div class="dataTables_info" role="alert" aria-live="polite" aria-relevant="all">
共${pager.totalCount}条记录 ${pager.page}/${pager.totalPageNum}
</div>
</div>
<div class="col-sm-6">
<div class="dataTables_paginate paging_simple_numbers">
<ul class="pagination">
<c:if test="${pager.page - 2 gt 2}">
<li class="paginate_button previous" aria-controls="DataTables_Table_0" tabindex="0" id="DataTables_Table_0_previous">
<a href="javascript:;" onclick="toPage(${pager.page - 1})">上一页</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(1)">1</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;">...</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page - 2})">${pager.page - 2}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page - 1})">${pager.page - 1}</a>
</li>
</c:if>

<c:if test="${pager.page == 4}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(1)">1</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page - 2})">${pager.page - 2}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page - 1})">${pager.page - 1}</a>
</li>
</c:if>

<c:if test="${pager.page - 2 lt 2}">
<c:if test="${pager.page == 3}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(1)">1</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(2)">2</a>
</li>
</c:if>
<c:if test="${pager.page == 2}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(1)">1</a>
</li>
</c:if>
</c:if>

<!-- 当前页 -->
<li class="paginate_button active" aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;">${pager.page}</a>
</li>

<c:if test="${pager.page + 3 lt pager.totalPageNum}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 1})">${pager.page + 1}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 2})">${pager.page + 2}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;">...</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.totalPageNum})">${pager.totalPageNum}</a>
</li>
<li class="paginate_button next" aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 1})">下一页</a>
</li>
</c:if>
<c:if test="${pager.page + 3 == pager.totalPageNum}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 1})">${pager.page + 1}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 2})">${pager.page + 2}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 3})">${pager.page + 3}</a>
</li>
</c:if>
<c:if test="${pager.page + 3 gt pager.totalPageNum}">
<c:if test="${pager.page == pager.totalPageNum -1}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 1})">${pager.page + 1}</a>
</li>
</c:if>
<c:if test="${pager.page == pager.totalPageNum -2}">
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 1})">${pager.page + 1}</a>
</li>
<li class="paginate_button " aria-controls="DataTables_Table_0" tabindex="0">
<a href="javascript:;" onclick="toPage(${pager.page + 2})">${pager.page + 2}</a>
</li>
</c:if>
</c:if>
</ul>
</div>
</div>
</div>
</c:if>

js

$(function(){
//alert(1);
// 加载文章列表
loadArticleList();
});



// 加载文章列表
function loadArticleList(){
//alert(2);
// 收集参数
var param = buildParam();
// alert(param);
//分页相关操作
var page = $("#page").val();
if(isEmpty(page) || page == 0){
page = 1;
}

$.ajax({
url : '/article/load',
data : 'page='+page+"¶m="+param,
type : "post",
success : function(data) {
//alert(data);
$("#dataList").html(data);
}
});

}


// 收集参数:前端传递的参数进行获取
function buildParam(){
//alert(3);
var param = {};
var keyword = $("#keyword").val();
if(!isEmpty(keyword)){
param["title"] = encodeURI(encodeURI(keyword));
}

var categoryId = $("#categoryId").val();
if(!isEmpty(categoryId) && categoryId != '-1'){
param["categoryId"] = categoryId;
}

var tagId = $("#tagId").val();
if(!isEmpty(tagId) && tagId != '-1'){
param["tagId"] = tagId;
}
return JSON.stringify(param);
}


// 搜索
function search(){
loadArticleList();
}

// 新增文章 跳转新页
function addArticle(){
window.location.href = "/article/add";
}

// 删除文章
function deleteArticle(id){
$.ajax({
url : '../article/delete',
data : 'id='+id,
success : function(data) {
if(data.resultCode == 'success'){
autoCloseAlert(data.errorInfo,1000);
loadArticleList();
}else{
autoCloseAlert(data.errorInfo,1000);
}
}
});
}

function htmlArticle(id){
$.ajax({
url : '../article/static/'+id,
success : function(data) {
if(data.resultCode == 'success'){
autoCloseAlert(data.errorInfo,1000);
loadArticleList();
}else{
autoCloseAlert(data.errorInfo,1000);
}
}
});
}

// 静态化全部文章
function htmlAllArticle(){
$("#htmlAll").hide();
$.ajax({
url : '../article/staticAll',
success : function(data) {
if(data.resultCode == 'success'){
autoCloseAlert(data.errorInfo,1000);
loadArticleList();
}else{
autoCloseAlert(data.errorInfo,1000);
}
$("#htmlAll").show();
}
});
}

// 编辑文章
function editArticle(id){
window.location.href = "../article/editJump/"+id;
}

function toPage(page){
$("#page").val(page);
loadArticleList();
}

//0:可用 1:不可用
function updateStatue(id,flag){
$.ajax({
url : '/article/updateStatue',
data : 'id='+id+'&status='+flag,
success : function(data) {
if(data.resultCode == 'success'){
autoCloseAlert(data.errorInfo,1000);
loadArticleList();
}else{
autoCloseAlert(data.errorInfo,1000);
}
}
});
}

部署至服务器

按类别查询

SSM框架实战-搭建自己的个人博客4-文章管理与展示_List_02

按标签查询

SSM框架实战-搭建自己的个人博客4-文章管理与展示_分页_03

模糊查询

SSM框架实战-搭建自己的个人博客4-文章管理与展示_数据_04

更改状态

SSM框架实战-搭建自己的个人博客4-文章管理与展示_List_05

新增先登录

SSM框架实战-搭建自己的个人博客4-文章管理与展示_数据_06