在线博客系统——文章列表

目录

接口说明

数据表结构

Dao持久层

pojo实体类

mapper接口

service业务逻辑层

接口

实现类

vo包

vo实体类(负责与前端数据交互)

统一处理结果集Result

接收前端参数PageParams

Controller控制层

前端测试


接口说明

接口url:/articles

请求方式:POST

请求参数:

参数名称参数类型说明
pageint当前页数
pageSizeint每页显示的数量

返回数据json:

{
    "success": true,
    "code": 200,
    "msg": "success",
    "data": [
        {
            "id": 1,
            "title": "springboot介绍以及入门案例",
            "summary": "通过Spring Boot实现的服务,只需要依靠一个Java类,把它打包成jar,并通过`java -jar`命令就可以运行起来。\r\n\r\n这一切相较于传统Spring应用来说,已经变得非常的轻便、简单。",
            "commentCounts": 2,
            "viewCounts": 54,
            "weight": 1,
            "createDate": "2609-06-26 15:58",
            "author": "12",
            "body": null,
            "tags": [
                {
                    "id": 5,
                    "avatar": null,
                    "tagName": "444"
                },
                {
                    "id": 7,
                    "avatar": null,
                    "tagName": "22"
                },
                {
                    "id": 8,
                    "avatar": null,
                    "tagName": "11"
                }
            ],
            "categorys": null
        },
        {
            "id": 9,
            "title": "Vue.js 是什么",
            "summary": "Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。",
            "commentCounts": 0,
            "viewCounts": 3,
            "weight": 0,
            "createDate": "2609-06-27 11:25",
            "author": "12",
            "body": null,
            "tags": [
                {
                    "id": 7,
                    "avatar": null,
                    "tagName": "22"
                }
            ],
            "categorys": null
        },
        {
            "id": 10,
            "title": "Element相关",
            "summary": "本节将介绍如何在项目中使用 Element。",
            "commentCounts": 0,
            "viewCounts": 3,
            "weight": 0,
            "createDate": "2609-06-27 11:25",
            "author": "12",
            "body": null,
            "tags": [
                {
                    "id": 5,
                    "avatar": null,
                    "tagName": "444"
                },
                {
                    "id": 6,
                    "avatar": null,
                    "tagName": "33"
                },
                {
                    "id": 7,
                    "avatar": null,
                    "tagName": "22"
                },
                {
                    "id": 8,
                    "avatar": null,
                    "tagName": "11"
                }
            ],
            "categorys": null
        }
    ]
}

数据表结构

文章表:

CREATE TABLE `ms_article` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `comment_counts` INT(11) DEFAULT NULL COMMENT '评论数量',
  `create_date` BIGINT(20) DEFAULT NULL COMMENT '创建时间',
  `summary` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '简介',
  `title` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '标题',
  `view_counts` INT(11) DEFAULT NULL COMMENT '浏览数量',
  `weight` INT(11) NOT NULL COMMENT '是否置顶',
  `author_id` BIGINT(20) DEFAULT NULL COMMENT '作者id',
  `body_id` BIGINT(20) DEFAULT NULL COMMENT '内容id',
  `category_id` INT(11) DEFAULT NULL COMMENT '类别id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=1541273877395615747 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

文章内容表:

CREATE TABLE `ms_article_body` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `content` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 'makedown格式的信息',
  `content_html` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 'html格式的信息',
  `article_id` BIGINT(20) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `article_id` (`article_id`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=1541273877852794882 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

文章分类表:

CREATE TABLE `ms_category` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `avatar` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '分类图标路径',
  `category_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图标分类的名称',
  `description` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '分类的描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

标签表:

CREATE TABLE `ms_tag` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `avatar` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `tag_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

文章、标签关联表:通过文章id可以间接查到标签id

CREATE TABLE `ms_article_tag` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `article_id` BIGINT(20) NOT NULL,
  `tag_id` BIGINT(20) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `article_id` (`article_id`) USING BTREE,
  KEY `tag_id` (`tag_id`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=1541273877785686019 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

用户表:

CREATE TABLE `ms_sys_user` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `account` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '账号',
  `admin1` BIT(1) DEFAULT NULL COMMENT '是否管理员',
  `avatar` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '头像',
  `create_date` BIGINT(20) DEFAULT NULL COMMENT '注册时间',
  `deleted` BIT(1) DEFAULT NULL COMMENT '是否删除',
  `email` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '邮箱',
  `last_login` BIGINT(20) DEFAULT NULL COMMENT '最后登录时间',
  `mobile_phone_number` VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机号',
  `nickname` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '昵称',
  `password` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '密码',
  `salt` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '加密盐',
  `status` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '状态',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=1540200900662992899 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

Dao持久层

pojo实体类

Article:
package com.huing.blog.dao.pojo;

import lombok.Data;

/**
 * @author huing
 * @create 2022-07-03 10:27
 */
@Data
public class Article {

    public static final int Article_TOP = 1;

    public static final int Article_Common = 0;

    private Long id;

    /**
     * 标题
     */
    private String title;

    /**
     * 简介
     */
    private String summary;

    /**
     * 评论数量
     */
    private Integer commentCounts;

    /**
     * 浏览数量
     */
    private Integer viewCounts;

    /**
     * 作者id
     */
    private Long authorId;
    /**
     * 内容id
     */
    private Long bodyId;
    /**
     * 类别id
     */
    private Long categoryId;

    /**
     * 置顶
     */
//    private Integer weight = Article_Common;
    private Integer weight;


    /**
     * 创建时间
     */
    private Long createDate;
}

文章内容ArticleBody:

package com.huing.blog.dao.pojo;

import lombok.Data;

/**
 * 内容表
 * @author huing
 * @create 2022-06-24 15:48
 */
@Data
public class ArticleBody {

    private Long id;
    /**
     * makedown格式的信息
     */
    private String content;

    /**
     * html格式的信息
     */
    private String contentHtml;
    private Long articleId;
}

类别表Category :

package com.huing.blog.dao.pojo;

import lombok.Data;

/**
 * 类别表
 * @author huing
 * @create 2022-06-24 15:52
 */
@Data
public class Category {

    private Long id;

    /**
     * 分类图标路径
     */
    private String avatar;

    /**
     * 图标分类的名称
     */
    private String categoryName;

    /**
     * 分类的描述
     */
    private String description;
}

用户SysUser:

package com.huing.blog.dao.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

/**
 * 用户
 *
 * @author huing
 * @create 2022-06-11 19:02
 */
@Data
public class SysUser {

    //    @TableId(type = IdType.ASSIGN_ID) //默认id类型
// 以后 用户多了之后,要进行分表操作,id就需要用分布式id了
//    @TableId(type = IdType.AUTO) 数据库自增
    private Long id;

    /**
     * 账号
     */
    private String account;

    /**
     * 是否管理员
     */
    private Integer admin1;

    /**
     * 头像
     */
    private String avatar;

    /**
     * 注册时间
     */
    private Long createDate;

    /**
     * 是否删除
     */
    private Integer deleted;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 最后登录时间
     */
    private Long lastLogin;

    /**
     * 手机号
     */
    private String mobilePhoneNumber;

    /**
     * 昵称
     */
    private String nickname;

    /**
     * 密码
     */
    private String password;

    /**
     * 加密盐
     */
    private String salt;

    /**
     * 状态
     */
    private String status;
}

标签Tag:
 

package com.huing.blog.dao.pojo;

import lombok.Data;

/**
 * 标签
 * @author huing
 * @create 2022-06-11 19:04
 */
@Data
public class Tag {

    private Long id;

    private String avatar;

    private String tagName;

}

mapper接口

添加@Mapper注解,以防止Service引用爆红

ArticleMapper:

package com.huing.blog.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huing.blog.dao.pojo.Article;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;


/**
 * @author huing
 * @create 2022-06-11 19:00
 */
@Mapper
public interface ArticleMapper extends BaseMapper<Article> {
    
    /**
     * 根据条件查询文章详情
     * @param page          代表我们自定义的分页查询
     * @param categoryId    类别id
     * @param tagId         标签id
     * @param year          年
     * @param month         月
     * @return
     */
    //Page对象 是mybatisplus的page对象 代表要用到mybatisplus的一个分页
    //IPage也是mybatisplus的,代表我们自定义的分页查询
    IPage<Article> listArticle(@Param("page") Page<Article> page,
                               @Param("categoryId") Long categoryId,
                               @Param("tagId") Long tagId,
                               @Param("year") String year,
                               @Param("month") String month);
}

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.huing.blog.dao.mapper.ArticleMapper">
    <resultMap id="articleMap" type="com.huing.blog.dao.pojo.Article">
        <id column="id" property="id"/>
        <result column="author_id" property="authorId"/>
        <result column="comment_counts" property="commentCounts"/>
        <result column="create_date" property="createDate"/>
        <result column="summary" property="summary"/>
        <result column="title" property="title"/>
        <result column="view_counts" property="viewCounts"/>
        <result column="weight" property="weight"/>
        <result column="body_id" property="bodyId"/>
        <result column="category_id" property="categoryId"/>
    </resultMap>

    <!--    IPage<Article> listArticle(Page<Article> page,Long categoryId, Long tagId, String year, String month);-->
    <select id="listArticle" resultMap="articleMap">
        select * from ms_article
        <where>
            1 = 1
            <if test="categoryId != null">
                and category_id=#{categoryId}
            </if>
            <if test="tagId != null">
                and id in (select article_id from ms_article_tag where tag_id=#{tagId})
            </if>
            <if test="year != null and year.length>0 and month != null and month.length>0">
                and (FROM_UNIXTIME(create_date/1000,'%Y') =#{year} and
                FROM_UNIXTIME(create_date/1000,'%m')=#{month})
            </if>
        </where>
        order by weight desc,create_date desc
    </select>
</mapper>

ArticleBodyMapper:

package com.huing.blog.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huing.blog.dao.pojo.ArticleBody;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author huing
 * @create 2022-07-03 15:16
 */
@Mapper
public interface ArticleBodyMapper extends BaseMapper<ArticleBody> {
}

CategoryMapper:

package com.huing.blog.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huing.blog.dao.pojo.Category;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author huing
 * @create 2022-07-03 15:19
 */
@Mapper
public interface CategoryMapper extends BaseMapper<Category> {
}

SysUserMapper:

package com.huing.blog.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huing.blog.dao.pojo.SysUser;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author huing
 * @create 2022-06-11 19:05
 */
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
}

TagMapper:

package com.huing.blog.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huing.blog.dao.pojo.Tag;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author huing
 * @create 2022-06-11 19:05
 */
@Mapper
public interface TagMapper extends BaseMapper<Tag> {

    List<Tag> findTagsByArticleId(Long articleId);
}

service业务逻辑层

接口

ArticleService:

package com.huing.blog.service;

import com.huing.blog.vo.ArticleVo;
import com.huing.blog.vo.Result;
import com.huing.blog.vo.params.PageParams;

import java.util.List;

/**
 * @author huing
 * @create 2022-07-03 10:42
 */
public interface ArticleService {
    /**
     * 分页查询文章列表
     * @param pageParams
     * @return
     */
    Result<List<ArticleVo>> listArticle(PageParams pageParams);
}

CategoryService:

package com.huing.blog.service;

import com.huing.blog.vo.CategoryVo;

/**
 * @author huing
 * @create 2022-07-03 15:20
 */
public interface CategoryService {
    /**
     * 根据id查询分类信息
     * @param categoryId
     * @return
     */
    CategoryVo findCategoryById(Long categoryId);
}

SysUserService:

package com.huing.blog.service;

import com.huing.blog.dao.pojo.SysUser;

/**
 * @author huing
 * @create 2022-07-03 11:47
 */
public interface SysUserService {

    /**
     * 根据id查询user
     * @param id
     * @return
     */
    SysUser findUserById(Long id);
}

TagService:

package com.huing.blog.service;

import com.huing.blog.vo.TagVo;

import java.util.List;

/**
 * @author huing
 * @create 2022-07-03 11:30
 */
public interface TagService {
    /**
     * 根据文章id查询该文章的tag标签
     * @param articleId
     * @return
     */
    List<TagVo> findTagsByArticleId(Long articleId);
}

实现类

ArticleServiceImpl:

package com.huing.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huing.blog.dao.mapper.ArticleBodyMapper;
import com.huing.blog.dao.mapper.ArticleMapper;
import com.huing.blog.dao.pojo.Article;
import com.huing.blog.dao.pojo.ArticleBody;
import com.huing.blog.dao.pojo.SysUser;
import com.huing.blog.service.ArticleService;
import com.huing.blog.service.CategoryService;
import com.huing.blog.service.SysUserService;
import com.huing.blog.service.TagService;
import com.huing.blog.vo.ArticleBodyVo;
import com.huing.blog.vo.ArticleVo;
import com.huing.blog.vo.Result;
import com.huing.blog.vo.UserVo;
import com.huing.blog.vo.params.PageParams;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author huing
 * @create 2022-07-03 11:01
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private TagService tagService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private CategoryService categoryService;

    @Override
    public Result<List<ArticleVo>> listArticle(PageParams pageParams) {
        Page<Article> page = new Page<>(pageParams.getPage(), pageParams.getPageSize());
        IPage<Article> articleIPage =  articleMapper.listArticle(
                page,
                pageParams.getCategoryId(),
                pageParams.getTagId(),
                pageParams.getYear(),
                pageParams.getMonth());
        List<Article> records = articleIPage.getRecords();
        return Result.success(copyList(records,true,true));
    }

    private List<ArticleVo> copyList(List<Article> records, boolean isTag, boolean isAuthor) {
        List<ArticleVo> articleVoList = new ArrayList<>();
        for (Article record : records) {
            articleVoList.add(copy(record,isTag,isAuthor,false,false));
        }
        return articleVoList;
    }

    private ArticleVo copy(Article article, boolean isTag, boolean isAuthor, boolean isBody, boolean isCategory) {
        ArticleVo articleVo = new ArticleVo();
        articleVo.setId(String.valueOf(article.getId()));
        BeanUtils.copyProperties(article,articleVo);
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));

        //并不是所有的接口,都需要标签,作者信息
        if (isTag){
            Long articleId = article.getId();
            articleVo.setTags(tagService.findTagsByArticleId(articleId));
        }
        if (isAuthor){
            Long authorId = article.getAuthorId();
            SysUser sysUser = sysUserService.findUserById(authorId);
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(sysUser,userVo);
            userVo.setId(String.valueOf(sysUser.getId()));
            articleVo.setAuthor(userVo);
        }
        if (isBody){
            Long bodyId = article.getBodyId();
            articleVo.setBody(findarticleBodyByid(bodyId));
        }
        if (isCategory){
            Long categoryId = article.getCategoryId();
            articleVo.setCategory(categoryService.findCategoryById(categoryId));
        }
        return articleVo;
    }


    @Autowired
    private ArticleBodyMapper articleBodyMapper;

    /**
     * 根据BodyId查询 文章详情内容
     * @param bodyId
     * @return
     */
    private ArticleBodyVo findarticleBodyByid(Long bodyId) {

        ArticleBody articleBody = articleBodyMapper.selectById(bodyId);
        ArticleBodyVo articleBodyVo = new ArticleBodyVo();
        articleBodyVo.setContent(articleBody.getContent());
        return articleBodyVo;
    }
}

CategoryServiceImpl:

package com.huing.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huing.blog.dao.mapper.CategoryMapper;
import com.huing.blog.dao.pojo.Category;
import com.huing.blog.service.CategoryService;
import com.huing.blog.vo.CategoryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author huing
 * @create 2022-07-03 15:20
 */
@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public CategoryVo findCategoryById(Long categoryId) {
        Category category = categoryMapper.selectById(categoryId);
        CategoryVo categoryVo = new CategoryVo();
        BeanUtils.copyProperties(category,categoryVo);
        categoryVo.setId(String.valueOf(category.getId()));
        return categoryVo;
    }
}

SysUserServiceImpl:

package com.huing.blog.service.impl;

import com.huing.blog.dao.mapper.SysUserMapper;
import com.huing.blog.dao.pojo.SysUser;
import com.huing.blog.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author huing
 * @create 2022-07-03 11:47
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public SysUser findUserById(Long id) {
        SysUser sysUser = sysUserMapper.selectById(id);
        if (sysUser == null){
            sysUser = new SysUser();
            sysUser.setNickname("huing");
        }
        return sysUser;
    }
}

TagServiceImpl:

package com.huing.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huing.blog.dao.mapper.TagMapper;
import com.huing.blog.dao.pojo.Tag;
import com.huing.blog.service.TagService;
import com.huing.blog.vo.TagVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author huing
 * @create 2022-07-03 11:30
 */
@Service
public class TagServiceImpl implements TagService {

    @Autowired
    private TagMapper tagMapper;

    @Override
    public List<TagVo> findTagsByArticleId(Long articleId) {

        LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();
        List<Tag> tags = tagMapper.findTagsByArticleId(articleId);
        return copyList(tags);
    }

    private List<TagVo> copyList(List<Tag> tags) {
        List<TagVo> tagVoList = new ArrayList<>();

        for (Tag tag : tags) {
            tagVoList.add(copy(tag));
        }
        return tagVoList;
    }

    private TagVo copy(Tag tag) {
        TagVo tagVo = new TagVo();
        BeanUtils.copyProperties(tag,tagVo);
        tagVo.setId(String.valueOf(tag.getId()));
        return tagVo;
    }


}

vo包

vo实体类(负责与前端数据交互)

ArticleBodyVo:

package com.huing.blog.vo;

import lombok.Data;

/**
 * @author huing
 * @create 2022-06-24 16:00
 */
@Data
public class ArticleBodyVo {
    //内容
    private String content;
}

ArticleVo:

package com.huing.blog.vo;

import lombok.Data;

import java.util.List;

/**
 * @author huing
 * @create 2022-06-11 20:22
 */

@Data
public class ArticleVo {

    //    @JsonSerialize(using = ToStringSerializer.class)
    private String id;

    /**
     * 标题
     */
    private String title;

    /**
     * 简介
     */
    private String summary;

    /**
     * 评论数量
     */
    private Integer commentCounts;

    /**
     * 浏览数量
     */
    private Integer viewCounts;

    /**
     * 置顶
     */
    private Integer weight;

    /**
     * 创建时间
     */
    private String createDate;

    /**
     * 作者
     */
//    private String author;
    private UserVo author;


    private ArticleBodyVo body;

    /**
     * 标签
     */
    private List<TagVo> tags;

    private CategoryVo category;

}

CategoryVo:

package com.huing.blog.vo;

import lombok.Data;

/**
 * @author huing
 * @create 2022-06-24 16:00
 */
@Data
public class CategoryVo {
    //id,图标路径,图标名称

//    @JsonSerialize(using = ToStringSerializer.class)
    private String id;

    private String avatar;

    private String categoryName;

    private String description;
}

TagVo:

package com.huing.blog.vo;

import lombok.Data;

/**
 * 页面交互的数据
 * @author huing
 * @create 2022-06-11 20:24
 */
@Data
public class TagVo {

    private String id;

    private String tagName;

    private String avatar;
}

UserVo:

package com.huing.blog.vo;

import lombok.Data;

/**
 * @author huing
 * @create 2022-06-25 11:11
 */
@Data
public class UserVo {

    /**
     * 昵称
     */
    private String nickname;

    /**
     * 头像
     */
    private String avatar;

    /**
     * id
     */
//    @JsonSerialize(using = ToStringSerializer.class)
    private String  id;
}

统一处理结果集Result

package com.huing.blog.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 统一最后的结果
 * @author huing
 * @create 2022-06-11 20:01
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {

    /**
     * 成功
     */
    private boolean success;

    /**
     * 编码
     */
    private int code;

    /**
     * 信息
     */
    private String msg;

    /**
     * 数据
     */
    private T data;

    public static Result success(Object data) {
        return new Result(true,200,"success",data);
    }
    public static Result fail(Integer code, String msg) {
        return new Result(false,code,msg,null);
    }
}

接收前端参数PageParams

package com.huing.blog.vo.params;

import lombok.Data;

/**
 * @author huing
 * @create 2022-06-11 19:57
 */
@Data
public class PageParams {

    private int page = 1;

    private int pageSize = 10;

    private Long categoryId;

    private Long tagId;

    private String year;

    private String month;

    public String getMonth(){
        if (this.month != null && this.month.length() == 1){
            return "0" + this.month;
        }
        return this.month;
    }
}

Controller控制层

ArticleController:

package com.huing.blog.controller;

import com.huing.blog.service.ArticleService;
import com.huing.blog.vo.ArticleVo;
import com.huing.blog.vo.Result;
import com.huing.blog.vo.params.PageParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author huing
 * @create 2022-07-03 10:20
 */
@RestController
@RequestMapping("articles")
public class ArticleController {

    @Autowired
    private ArticleService articleService;


    /**
     * 首页,文章处理
     *
     * @param pageParams
     * @return
     */
    @PostMapping()
    public Result<List<ArticleVo>> listArticle(@RequestBody PageParams pageParams) {

        return articleService.listArticle(pageParams);
    }
}

前端测试

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PHP和MySQL是一对常见的Web开发工具,用于构建动态网站。博客系统是Web开发中的一个常见项目,可以用来展示个人或组织的文章和信息。下面是一个简单的PHP+MySQL博客系统的实现步骤: 1. 数据库设计 首先,需要设计数据库结构。这个博客系统需要保存文章、用户和评论信息,可以设计三个:articles、users和comments。 articles: | 字段名 | 数据类型 | 说明 | | ------ | -------- | ---- | | id | int | 主键 | | title | varchar | 标题 | | content| text | 内容 | | author | int | 作者id | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | users: | 字段名 | 数据类型 | 说明 | | ------ | -------- | ---- | | id | int | 主键 | | username | varchar | 用户名 | | password | varchar | 密码 | | email | varchar | 电子邮件 | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | comments: | 字段名 | 数据类型 | 说明 | | ------ | -------- | ---- | | id | int | 主键 | | content| text | 内容 | | article_id | int | 文章id | | user_id | int | 用户id | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | 2. 创建数据库连接 使用PHP代码创建与MySQL数据库的连接。 ```php $host = 'localhost'; $user = 'root'; $password = 'password'; $dbname = 'blog'; $conn = new mysqli($host, $user, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } ``` 3. 显示文章列表 使用SQL查询获取文章列表,并在网页上显示出来。 ```php $sql = "SELECT * FROM articles ORDER BY updated_at DESC"; $result = $conn->query($sql); if ($result->num_rows > 0) { // 输出数据 while($row = $result->fetch_assoc()) { echo "<a href='article.php?id=" . $row["id"] . "'>" . $row["title"] . "</a><br>"; } } else { echo "0 results"; } ``` 4. 显示文章内容 使用SQL查询获取指定文章的内容,并在网页上显示出来。 ```php $id = $_GET['id']; $sql = "SELECT * FROM articles WHERE id=" . $id; $result = $conn->query($sql); if ($result->num_rows > 0) { // 输出数据 while($row = $result->fetch_assoc()) { echo "<h1>" . $row["title"] . "</h1>"; echo "<p>" . $row["content"] . "</p>"; } } else { echo "0 results"; } ``` 5. 发布文章 在网页上提供单,用户可以输入文章标题和内容,将数据保存到数据库中。 ```php if ($_SERVER["REQUEST_METHOD"] == "POST") { $title = $_POST['title']; $content = $_POST['content']; $author = $_SESSION['user_id']; $now = date('Y-m-d H:i:s'); $sql = "INSERT INTO articles (title, content, author, created_at, updated_at) VALUES ('$title', '$content', '$author', '$now', '$now')"; if ($conn->query($sql) === TRUE) { echo "New article created successfully"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } } ``` 6. 用户认证 使用PHP代码实现用户登录和注册功能。 ```php session_start(); if ($_SERVER["REQUEST_METHOD"] == "POST") { // login $username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $result = $conn->query($sql); if ($result->num_rows > 0) { // set session variable $_SESSION['user_id'] = $result->fetch_assoc()['id']; header('Location: index.php'); exit(); } else { echo "Invalid username or password"; } } if ($_SERVER["REQUEST_METHOD"] == "POST") { // register $username = $_POST['username']; $password = $_POST['password']; $email = $_POST['email']; $now = date('Y-m-d H:i:s'); $sql = "INSERT INTO users (username, password, email, created_at, updated_at) VALUES ('$username', '$password', '$email', '$now', '$now')"; if ($conn->query($sql) === TRUE) { echo "New user created successfully"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } } ``` 7. 发评论 在文章页面下方提供单,用户可以输入评论内容,将数据保存到数据库中。 ```php if ($_SERVER["REQUEST_METHOD"] == "POST") { $content = $_POST['content']; $article_id = $_POST['article_id']; $user_id = $_SESSION['user_id']; $now = date('Y-m-d H:i:s'); $sql = "INSERT INTO comments (content, article_id, user_id, created_at, updated_at) VALUES ('$content', '$article_id', '$user_id', '$now', '$now')"; if ($conn->query($sql) === TRUE) { echo "New comment created successfully"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } } ``` 这是一个简单的PHP+MySQL博客系统的实现步骤,可以根据需要进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hxung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值