springboot实战项目——个人博客系统

1.项目介绍

1.1项目效果

博客首页

springboot实战项目——个人博客系统_第1张图片

登录功能 

 springboot实战项目——个人博客系统_第2张图片

注册功能

springboot实战项目——个人博客系统_第3张图片

文章分类 

 springboot实战项目——个人博客系统_第4张图片

文章归档 

springboot实战项目——个人博客系统_第5张图片

文章页面 

  

发布文章 (集成富文本编译器)

 springboot实战项目——个人博客系统_第6张图片

 1.2项目使用技术

前端:

  • vue
  • element-ui

 后端:

  • Springboot
  • mybatis-plus
  • redis
  • mysql
  • jwt

2.工程搭建

2.1新建springboot项目

springboot实战项目——个人博客系统_第7张图片

2.2在maven中导入相关依赖



        
            org.springframework.boot
            spring-boot-starter
            
            
                
                    org.springframework.boot
                    spring-boot-starter-logging
                
            
        

        
            org.springframework.boot
            spring-boot-starter-web
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.projectlombok
            lombok
        

        
            com.qiniu
            qiniu-java-sdk
            [7.7.0, 7.7.99]
        

        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
            org.springframework.boot
            spring-boot-starter-aop
        

        
            org.springframework.boot
            spring-boot-starter-mail
        

        
        
            com.alibaba
            fastjson
            1.2.76
        

        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
            org.springframework.boot
            spring-boot-starter-log4j2
        

        
            org.springframework.boot
            spring-boot-starter-aop
        

        
            org.springframework.boot
            spring-boot-starter-mail
        


        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.3
        

        
            joda-time
            joda-time
            2.10.10
        

        
            org.apache.commons
            commons-lang3
        

        
            commons-codec
            commons-codec
            1.15
        
        
            commons-collections
            commons-collections
            3.2.2
        

        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
        
            io.jsonwebtoken
            jjwt
            0.9.1
        

    

 2.3配置文件

mybatis-plus分页插件

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.leggasai.dao.mapper")
public class MybatisPlusConfig {
    //分页插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

跨域配置文件

import com.leggasai.handler.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //跨域配置
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8080")
                .allowedMethods("GET","POST","PUT","OPTIONS","DELETE")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

springboot配置文件 application.yml

server:
  port: 8888


spring:
  datasource:
    username: "mysql用户名"
    password: "mysql密码"
    url: jdbc:mysql://localhost:3306/blog?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
  redis:
    host: localhost
    port: 6379
  servlet:
    multipart:
      max-file-size: 2MB
      max-request-size: 20MB

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#mysql中表前缀为ms_
  global-config:
    db-config:
      table-prefix: ms_
  type-aliases-package: com.leggasai.dao.pojo
  mapper-locations: classpath*:mapper/*.xml

2.4特殊类

异常类:用于统一处理异常

package com.leggasai.handler;


import com.leggasai.vo.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

//对加了@controller注解的方法进行拦截处理 Aop的实现
@ControllerAdvice
public class AllExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseBody//返回json数据
    public Result doException(Exception ex){
        ex.printStackTrace();
        return Result.fail(-999, "系统异常");
    }
}

返回结果类:用于给前端返回数据 

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

@Data
@AllArgsConstructor
@NoArgsConstructor
//返回结果类
public class Result {
    private boolean success;
    private int code;
    private String msg;
    private Object data;
    //链式
    public static Result success(Object data){
        return new Result(true, 200, "success",data);
    }
    //链式
    public static Result fail(int code,String msg){
        return new Result(false,code,msg,null);
    }
}

异常码类:枚举类,用于显示不同的出错提示 

package com.leggasai.vo;

public enum  ErrorCode {

    PARAMS_ERROR(10001,"参数有误"),
    ACCOUNT_PWD_NOT_EXIST(10002,"用户名或密码不存在"),
    TOKEN_ERROR(10003,"token不合法"),
    ACCOUNT_EXISTED(10004,"账号已存在"),

    NO_PERMISSION(70001,"无访问权限"),
    SESSION_TIME_OUT(90001,"会话超时"),
    NO_LOGIN(90002,"未登录"),
    UPLOAD_ERROR(20001,"上传失败"),;
    private int code;
    private String msg;

    ErrorCode(int code, String msg){
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

3.数据库搭建 

在sqlyog(或navicat)中新建名为blog的数据库

3.1表一:ms_article文章表

CREATE TABLE `blog`.`ms_article`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT,
  `comment_counts` int(0) NULL DEFAULT NULL COMMENT '评论数量',
  `create_date` bigint(0) NULL DEFAULT NULL COMMENT '创建时间',
  `summary` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '简介',
  `title` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题',
  `view_counts` int(0) NULL DEFAULT NULL COMMENT '浏览数量',
  `weight` int(0) NOT NULL COMMENT '是否置顶',
  `author_id` bigint(0) NULL DEFAULT NULL COMMENT '作者id',
  `body_id` bigint(0) NULL DEFAULT NULL COMMENT '内容id',
  `category_id` int(0) NULL DEFAULT NULL COMMENT '类别id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

 3.2表二:ms_article_body文章内容表

drop table if exists `ms_article_body`;
create table `ms_article_body`  (
  `id` bigint(0) not null auto_increment,
  `content` longtext character set utf8 collate utf8_general_ci null,
  `content_html` longtext character set utf8 collate utf8_general_ci null,
  `article_id` bigint(0) not null,
  primary key (`id`) using btree,
  index `article_id`(`article_id`) using btree
) engine = innodb auto_increment = 1405916999854342147 character set = utf8 collate = utf8_general_ci row_format = dynamic;

 3.3表三:ms_article_tag关联表

 这个表是用于关联article表和tag表(文章标签表)

drop table if exists `ms_article_tag`;
create table `ms_article_tag`  (
  `id` bigint(0) not null auto_increment,
  `article_id` bigint(0) not null,
  `tag_id` bigint(0) not null,
  primary key (`id`) using btree,
  index `article_id`(`article_id`) using btree,
  index `tag_id`(`tag_id`) using btree
) engine = innodb auto_increment = 1405916999787233282 character set = utf8 collate = utf8_general_ci row_format = dynamic;

3.4表四:ms_sys_user用户表

drop table if exists `ms_sys_user`;
create table `ms_sys_user`  (
  `id` bigint(0) not null auto_increment,
  `account` varchar(64) character set utf8 collate utf8_general_ci null default null comment '账号',
  `admin` bit(1) null default null comment '是否管理员',
  `avatar` varchar(255) character set utf8 collate utf8_general_ci null default null comment '头像',
  `create_date` bigint(0) null default null comment '注册时间',
  `deleted` bit(1) null default null comment '是否删除',
  `email` varchar(128) character set utf8 collate utf8_general_ci null default null comment '邮箱',
  `last_login` bigint(0) null default null comment '最后登录时间',
  `mobile_phone_number` varchar(20) character set utf8 collate utf8_general_ci null default null comment '手机号',
  `nickname` varchar(255) character set utf8 collate utf8_general_ci null default null comment '昵称',
  `password` varchar(64) character set utf8 collate utf8_general_ci null default null comment '密码',
  `salt` varchar(255) character set utf8 collate utf8_general_ci null default null comment '加密盐',
  `status` varchar(255) character set utf8 collate utf8_general_ci null default null comment '状态',
  primary key (`id`) using btree
) engine = innodb auto_increment = 1404448588146192387 character set = utf8 collate = utf8_general_ci row_format = dynamic;

3.5表五: ms_tag文章标签表

drop table if exists `ms_tag`;
create table `ms_tag`  (
  `id` bigint(0) not null auto_increment,
  `avatar` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci null default null,
  `tag_name` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci null default null,
  primary key (`id`) using btree
) engine = innodb auto_increment = 11 character set = utf8 collate = utf8_general_ci row_format = dynamic;

3.6表六:ms_comment评论表 

drop table if exists `ms_comment`;
create table `ms_comment`  (
  `id` bigint(0) not null auto_increment,
  `content` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci not null,
  `create_date` bigint(0) not null,
  `article_id` int(0) not null,
  `author_id` bigint(0) not null,
  `parent_id` bigint(0) not null,
  `to_uid` bigint(0) not null,
  `level` varchar(1) character set utf8 collate utf8_general_ci not null,
  primary key (`id`) using btree,
  index `article_id`(`article_id`) using btree
) engine = innodb auto_increment = 1405209691876790275 character set = utf8 collate = utf8_general_ci row_format = dynamic;

3.7表七: ms_category类别表

drop table if exists `ms_category`;
create table `ms_category`  (
  `id` bigint(0) not null auto_increment,
  `avatar` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci null default null,
  `category_name` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci null default null,
  `description` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci null default null,
  primary key (`id`) using btree
) engine = innodb auto_increment = 6 character set = utf8 collate = utf8_general_ci row_format = dynamic;

4.首页功能

4.1文章列表实现

效果图

 springboot实战项目——个人博客系统_第8张图片

4.1.1pojo类 

 1.建立pojo类——article

package com.leggasai.dao.pojo;


import lombok.Data;

@Data
public class Article {
    public static final int Article_TOP=1;//是否指定,默认是
    public static final int Article_Common=0;//默认评论数0
    private Long id;//文章id
    private String title;//文章标题
    private String summary;//文章简介
    private Integer commentCounts;//文章评论数
    private Integer viewCounts;//文章阅读数
    private Long authorId;//作者id
    private Long bodyId;//文章内容id
    private Long categoryId;//文章类别id
    private Integer weight=Article_Common;//文章权重
    private Long createDate;//文章创建时间
}

 2.建立pojo类——sysUser用户类

package com.leggasai.dao.pojo;


import lombok.Data;

@Data
public class SysUser {
    private Long id;//用户id
    private String account;//用户账号
    private String password;//用户密码
    private Integer admin;//是否管理员
    private String avatar;//用户头像地址
    private Long createDate;//用户创建时间
    private Integer deleted;//是否被删除
    private String email;//用户邮箱
    private Long lastLogin;//用户最后一次登录时间
    private String nickname;//用户昵称
    private String mobilePhoneNumber;//用户手机号
    private String salt;//加密盐
    private String status;//用户状态

}

3.建立pojo类——tag标签类 

package com.leggasai.dao.pojo;
import lombok.Data;
@Data
public class Tag {
    private Long id;//标签id
    private String avatar;//标签图片地址
    private String tagName;//标签名
}

4.建立vo类——articleVo:前端显示类往往和数据库中的类有差别 


import java.util.List;

@Data
public class ArticleVo {

    private Long id;

    private String title;

    private String summary;

    private int commentCounts;

    private int viewCounts;

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

    private String author;

    private ArticleBodyVo body;

    private List tags;

    private List categorys;

}

4.1.2controller类

ArticleController类:用于处理和article相关业务

import java.util.List;

@RestController
@RequestMapping("articles")
public class ArticleController {

    @Autowired
    private ArticleService articleService;
	//Result是统一结果返回
    @PostMapping
    public Result articles(@RequestBody PageParams pageParams) {
        //ArticleVo 页面接收的数据
        List articles = articleService.listArticlesPage(pageParams);

        return Result.success(articles);
    }


}

 4.1.3service类

ArticleService接口与ArticleServiceImpl实现类

import java.util.List;

public interface ArticleService {

    List listArticlesPage(PageParams pageParams);

}
package com.leggasai.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.leggasai.common.aop.LogAnnotation;
import com.leggasai.dao.dos.Archives;
import com.leggasai.dao.mapper.ArticleBodyMapper;
import com.leggasai.dao.mapper.ArticleMapper;
import com.leggasai.dao.mapper.ArticleTagMapper;
import com.leggasai.dao.pojo.Article;
import com.leggasai.dao.pojo.ArticleBody;
import com.leggasai.dao.pojo.ArticleTag;
import com.leggasai.dao.pojo.SysUser;
import com.leggasai.service.*;
import com.leggasai.utils.UserThreadLocal;
import com.leggasai.vo.ArticleBodyVo;
import com.leggasai.vo.ArticleVo;
import com.leggasai.vo.Result;
import com.leggasai.vo.TagVo;
import com.leggasai.vo.params.ArticleParam;
import com.leggasai.vo.params.PageParams;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
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.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
   @Autowired
   private SysUserService sysUserService;
    @Autowired
    private TagsService tagsService;

    public ArticleVo copy(Article article,boolean isAuthor,boolean isBody,boolean isTags){
        ArticleVo articleVo = new ArticleVo();
        BeanUtils.copyProperties(article, articleVo);
        if (isAuthor) {
            SysUser sysUser = sysUserService.findSysUserById(article.getAuthorId());
            articleVo.setAuthor(sysUser.getNickname());
        }
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        if (isTags){
           List tags = tagsService.findTagsByArticleId(article.getId());
           articleVo.setTags(tags);
        }
        return articleVo;
    }

    private List copyList(List
records,boolean isAuthor,boolean isBody,boolean isTags) { List articleVoList = new ArrayList<>(); for (Article article : records) { ArticleVo articleVo = copy(article,isAuthor,isBody,isTags); articleVoList.add(articleVo); } return articleVoList; } @Override public List listArticlesPage(PageParams pageParams) { QueryWrapper
queryWrapper = new QueryWrapper<>(); Page
page = new Page<>(pageParams.getPage(),pageParams.getPageSize()); Page
articlePage = articleMapper.selectPage(page, queryWrapper); List articleVoList = copyList(articlePage.getRecords(),true,false,true); return articleVoList; } }

sysUserService和sysUserServiceImpl 

public interface UserService {

    SysUser findUserById(Long userId);
}
package com.leggasai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.leggasai.dao.mapper.SysUserMapper;
import com.leggasai.dao.pojo.SysUser;
import com.leggasai.service.LoginService;
import com.leggasai.service.SysUserService;
import com.leggasai.vo.ErrorCode;
import com.leggasai.vo.LoginUserVo;
import com.leggasai.vo.Result;
import com.leggasai.vo.UserVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public SysUser findUserById(Long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (sysUser == null) {
            sysUser = new SysUser();
            sysUser.setNickname("码神之路");
        }
        return sysUser;
    }
}

tagService和tagServiceImpl 

package com.leggasai.service;

import com.leggasai.vo.Result;
import com.leggasai.vo.TagVo;

import java.util.List;

public interface TagService {
    List findTagsByArticleId(Long articleId);
}
package com.leggasai.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.leggasai.dao.mapper.TagMapper;
import com.leggasai.dao.pojo.Tag;
import com.leggasai.service.TagService;
import com.leggasai.vo.Result;
import com.leggasai.vo.TagVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


@Service
public class TagServiceImpl implements TagService {
    @Autowired
    private TagMapper tagMapper;
    @Override
    public List findTagsByArticleId(Long articleId) {
        //mybatis-plus无法进行多表查询
        List tags=tagMapper.findTagsByArticleId(articleId);
        return copyList(tags);
    }


    public TagVo copy(Tag tag){
        TagVo tagVo=new TagVo();
        BeanUtils.copyProperties(tag,tagVo);
        tagVo.setId(String.valueOf(tag.getId()));
        return tagVo;
    }
    public List copyList(List tagList){
        List tagVoList = new ArrayList<>();
        for (Tag tag : tagList) {
            tagVoList.add(copy(tag));
        }
        return tagVoList;
    }



}

4.1.4dao层

ArticleMapper接口

package com.leggasai.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.leggasai.dao.dos.Archives;
import com.leggasai.dao.pojo.Article;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;
@Mapper
public interface ArticleMapper extends BaseMapper
{ List listArchives(); IPage
listArticle(Page
page, Long categoryId, Long tagId, String year, String month); }

SysUserMapper接口 

package com.leggasai.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.leggasai.dao.pojo.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
public interface SysUserMapper extends BaseMapper {
}

TagMapper接口 

package com.leggasai.dao.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.leggasai.dao.pojo.Tag;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;


import java.util.List;
@Mapper
public interface TagMapper extends BaseMapper {
    /*
    根据文章id查询标签列表
     */
    List findTagsByArticleId(Long articleId);

   
}

 TagMapper.xml







    

4.2首页最热标签功能

springboot实战项目——个人博客系统_第9张图片

 4.2.1前端接口

接口url:/tags/hot

请求方式:GET

请求参数:无

返回数据:

{
    "success": true,
    "code": 200,
    "msg": "success",
    "data": [
        {
            "id":1,
            "tagName":"4444"
        }
    ]
}

4.2.2controller类

    @GetMapping("/hot")
    public Result hot(){
        int limit =6;
        Result hots = tagService.hots(limit);
        return hots;
    }

4.2.3service层

    Result hots(int limit);
    @Override
    public Result hots(int limit) {
        /*
        标签所拥有的文章数量做多,就是最热标签
         */
        List tagIds=tagMapper.findHotsTagIds(limit);
        if(CollectionUtils.isEmpty(tagIds)){
            return Result.success(Collections.emptyList());
        }
        //需要的是tagId和tagName
        List tagList=tagMapper.findTagesByTagIds(tagIds);
        //System.out.println("最热标签");
        //System.out.println(tagList);
        return Result.success(tagList);
    }

4.2.4mapper层

    

    

4.3首页最热文章功能

springboot实战项目——个人博客系统_第10张图片

 

后续可以用cache优化

4.3.1前端接口

接口url:/articles/hot

请求方式:POST

请求参数:

返回数据:

{
    "success": true,
    "code": 200,
    "msg": "success",
    "data": [
        {
            "id": 1,
            "title": "springboot介绍以及入门案例",
        },
        {
            "id": 9,
            "title": "Vue.js 是什么",
        },
        {
            "id": 10,
            "title": "Element相关",
            
        }
    ]
}

4.3.2controller层

    @PostMapping("/hot")
    public Result hotArticle(){
        int limit =5;
        return articleService.hotArticle(limit);
    }

4.3.3service层

    @Override
    public Result hotArticle(int limit) {
        LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(Article::getViewCounts); queryWrapper.select(Article::getId,Article::getTitle); queryWrapper.last("limit "+limit); //select id,title from article order by view_counts desc limit 5 List
articles = articleMapper.selectList(queryWrapper); return Result.success(copyList(articles,false,false)); }

4.4首页最新文章功能

springboot实战项目——个人博客系统_第11张图片

 

后续可以用cache优化 

4.4.1前端接口

接口url:/articles/new

请求方式:POST

请求参数:

返回数据:

{
    "success": true,
    "code": 200,
    "msg": "success",
    "data": [
        {
            "id": 1,
            "title": "springboot介绍以及入门案例",
        },
        {
            "id": 9,
            "title": "Vue.js 是什么",
        },
        {
            "id": 10,
            "title": "Element相关",
            
        }
    ]
}

4.4.2controller层

    @PostMapping("/new")
    public Result newArticles(){
        int limit =5;
        return articleService.newArticles(limit);
    }

4.4.3service层

    @Override
    public Result newArticles(int limit) {
        LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(Article::getCreateDate); queryWrapper.select(Article::getId,Article::getTitle); queryWrapper.last("limit "+limit); //select id,title from article order by create_date desc limit 5 List
articles = articleMapper.selectList(queryWrapper); return Result.success(copyList(articles,false,false)); }

4.5首页文章归档功能

springboot实战项目——个人博客系统_第12张图片

 

4.5.1前端接口

接口url:/articles/listArchives

请求方式:POST

请求参数:

返回数据:

{
    "success": true,
    "code": 200,
    "msg": "success",
    "data": [
        {
            "year": "2021",
            "month": "6",
            "count": 2
        }
            
    ]

}

4.5.2controller层

    @PostMapping("listArchives")
    public Result listArchives(){
        return articleService.listArchives();
    }

4.5.3service层

    @Override
    public Result listArchives() {
        List archivesList=articleMapper.listArchives();
        return Result.success(archivesList);
    }

4.5.4mapper层 

    List listArchives();

注意数据库中create_date是时间戳,需要使用FROM_UNIXTIME转化为xxxx年xx月的格式!

    

 Archives类

package com.leggasai.dao.dos;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Archives {

    private Integer year;
    private Integer month;
    private Long count;

}

5.登录功能

5.1jwt技术

5.2退出功能

5.3注册功能

5.4登录拦截器

5.5ThreadLocal使用

未完待续~

你可能感兴趣的:(springboot,spring,boot,java)