当前位置:   article > 正文

springboot实战项目——个人博客系统_spring boot 实践之十三 10 spring boot综合项目实战——个人博客系统源码+文

spring boot 实践之十三 10 spring boot综合项目实战——个人博客系统源码+文件

1.项目介绍

1.1项目效果

博客首页

登录功能 

 

注册功能

文章分类 

 

文章归档 

文章页面 

  

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

 

 1.2项目使用技术

前端:

  • vue
  • element-ui

 后端:

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

2.工程搭建

2.1新建springboot项目

2.2在maven中导入相关依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter</artifactId>
  5. <!-- 排除 默认使用的logback -->
  6. <exclusions>
  7. <exclusion>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-logging</artifactId>
  10. </exclusion>
  11. </exclusions>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-web</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <scope>runtime</scope>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-test</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.projectlombok</groupId>
  29. <artifactId>lombok</artifactId>
  30. </dependency>
  31. <dependency>
  32. <groupId>com.qiniu</groupId>
  33. <artifactId>qiniu-java-sdk</artifactId>
  34. <version>[7.7.0, 7.7.99]</version>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-data-redis</artifactId>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-aop</artifactId>
  43. </dependency>
  44. <dependency>
  45. <groupId>org.springframework.boot</groupId>
  46. <artifactId>spring-boot-starter-mail</artifactId>
  47. </dependency>
  48. <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
  49. <dependency>
  50. <groupId>com.alibaba</groupId>
  51. <artifactId>fastjson</artifactId>
  52. <version>1.2.76</version>
  53. </dependency>
  54. <dependency>
  55. <groupId>org.springframework.boot</groupId>
  56. <artifactId>spring-boot-configuration-processor</artifactId>
  57. <optional>true</optional>
  58. </dependency>
  59. <dependency>
  60. <groupId>org.springframework.boot</groupId>
  61. <artifactId>spring-boot-starter-log4j2</artifactId>
  62. </dependency>
  63. <dependency>
  64. <groupId>org.springframework.boot</groupId>
  65. <artifactId>spring-boot-starter-aop</artifactId>
  66. </dependency>
  67. <dependency>
  68. <groupId>org.springframework.boot</groupId>
  69. <artifactId>spring-boot-starter-mail</artifactId>
  70. </dependency>
  71. <dependency>
  72. <groupId>com.baomidou</groupId>
  73. <artifactId>mybatis-plus-boot-starter</artifactId>
  74. <version>3.4.3</version>
  75. </dependency>
  76. <dependency>
  77. <groupId>joda-time</groupId>
  78. <artifactId>joda-time</artifactId>
  79. <version>2.10.10</version>
  80. </dependency>
  81. <dependency>
  82. <groupId>org.apache.commons</groupId>
  83. <artifactId>commons-lang3</artifactId>
  84. </dependency>
  85. <dependency>
  86. <groupId>commons-codec</groupId>
  87. <artifactId>commons-codec</artifactId>
  88. <version>1.15</version>
  89. </dependency>
  90. <dependency>
  91. <groupId>commons-collections</groupId>
  92. <artifactId>commons-collections</artifactId>
  93. <version>3.2.2</version>
  94. </dependency>
  95. <dependency>
  96. <groupId>org.springframework.boot</groupId>
  97. <artifactId>spring-boot-starter-data-redis</artifactId>
  98. </dependency>
  99. <!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
  100. <dependency>
  101. <groupId>io.jsonwebtoken</groupId>
  102. <artifactId>jjwt</artifactId>
  103. <version>0.9.1</version>
  104. </dependency>
  105. </dependencies>

 2.3配置文件

mybatis-plus分页插件

  1. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  2. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  3. import org.mybatis.spring.annotation.MapperScan;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. @MapperScan("com.leggasai.dao.mapper")
  8. public class MybatisPlusConfig {
  9. //分页插件
  10. @Bean
  11. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  12. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  13. interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
  14. return interceptor;
  15. }
  16. }

跨域配置文件

  1. import com.leggasai.handler.LoginInterceptor;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.servlet.config.annotation.CorsRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  6. @Configuration
  7. public class WebMvcConfig implements WebMvcConfigurer {
  8. @Override
  9. public void addCorsMappings(CorsRegistry registry) {
  10. //跨域配置
  11. registry.addMapping("/**")
  12. .allowedOrigins("http://localhost:8080")
  13. .allowedMethods("GET","POST","PUT","OPTIONS","DELETE")
  14. .allowCredentials(true)
  15. .maxAge(3600);
  16. }
  17. }

springboot配置文件 application.yml

  1. server:
  2. port: 8888
  3. spring:
  4. datasource:
  5. username: "mysql用户名"
  6. password: "mysql密码"
  7. url: jdbc:mysql://localhost:3306/blog?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
  8. driver-class-name: com.mysql.cj.jdbc.Driver
  9. redis:
  10. host: localhost
  11. port: 6379
  12. servlet:
  13. multipart:
  14. max-file-size: 2MB
  15. max-request-size: 20MB
  16. mybatis-plus:
  17. configuration:
  18. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  19. #mysql中表前缀为ms_
  20. global-config:
  21. db-config:
  22. table-prefix: ms_
  23. type-aliases-package: com.leggasai.dao.pojo
  24. mapper-locations: classpath*:mapper/*.xml

2.4特殊类

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

  1. package com.leggasai.handler;
  2. import com.leggasai.vo.Result;
  3. import org.springframework.web.bind.annotation.ControllerAdvice;
  4. import org.springframework.web.bind.annotation.ExceptionHandler;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. //对加了@controller注解的方法进行拦截处理 Aop的实现
  7. @ControllerAdvice
  8. public class AllExceptionHandler {
  9. @ExceptionHandler(Exception.class)
  10. @ResponseBody//返回json数据
  11. public Result doException(Exception ex){
  12. ex.printStackTrace();
  13. return Result.fail(-999, "系统异常");
  14. }
  15. }

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

  1. import lombok.AllArgsConstructor;
  2. import lombok.Data;
  3. import lombok.NoArgsConstructor;
  4. @Data
  5. @AllArgsConstructor
  6. @NoArgsConstructor
  7. //返回结果类
  8. public class Result {
  9. private boolean success;
  10. private int code;
  11. private String msg;
  12. private Object data;
  13. //链式
  14. public static Result success(Object data){
  15. return new Result(true, 200, "success",data);
  16. }
  17. //链式
  18. public static Result fail(int code,String msg){
  19. return new Result(false,code,msg,null);
  20. }
  21. }

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

  1. package com.leggasai.vo;
  2. public enum ErrorCode {
  3. PARAMS_ERROR(10001,"参数有误"),
  4. ACCOUNT_PWD_NOT_EXIST(10002,"用户名或密码不存在"),
  5. TOKEN_ERROR(10003,"token不合法"),
  6. ACCOUNT_EXISTED(10004,"账号已存在"),
  7. NO_PERMISSION(70001,"无访问权限"),
  8. SESSION_TIME_OUT(90001,"会话超时"),
  9. NO_LOGIN(90002,"未登录"),
  10. UPLOAD_ERROR(20001,"上传失败"),;
  11. private int code;
  12. private String msg;
  13. ErrorCode(int code, String msg){
  14. this.code = code;
  15. this.msg = msg;
  16. }
  17. public int getCode() {
  18. return code;
  19. }
  20. public void setCode(int code) {
  21. this.code = code;
  22. }
  23. public String getMsg() {
  24. return msg;
  25. }
  26. public void setMsg(String msg) {
  27. this.msg = msg;
  28. }
  29. }

3.数据库搭建 

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

3.1表一:ms_article文章表

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

 3.2表二:ms_article_body文章内容表

  1. drop table if exists `ms_article_body`;
  2. create table `ms_article_body` (
  3. `id` bigint(0) not null auto_increment,
  4. `content` longtext character set utf8 collate utf8_general_ci null,
  5. `content_html` longtext character set utf8 collate utf8_general_ci null,
  6. `article_id` bigint(0) not null,
  7. primary key (`id`) using btree,
  8. index `article_id`(`article_id`) using btree
  9. ) engine = innodb auto_increment = 1405916999854342147 character set = utf8 collate = utf8_general_ci row_format = dynamic;

 3.3表三:ms_article_tag关联表

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

  1. drop table if exists `ms_article_tag`;
  2. create table `ms_article_tag` (
  3. `id` bigint(0) not null auto_increment,
  4. `article_id` bigint(0) not null,
  5. `tag_id` bigint(0) not null,
  6. primary key (`id`) using btree,
  7. index `article_id`(`article_id`) using btree,
  8. index `tag_id`(`tag_id`) using btree
  9. ) engine = innodb auto_increment = 1405916999787233282 character set = utf8 collate = utf8_general_ci row_format = dynamic;

3.4表四:ms_sys_user用户表

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

3.5表五: ms_tag文章标签表

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

3.6表六:ms_comment评论表 

  1. drop table if exists `ms_comment`;
  2. create table `ms_comment` (
  3. `id` bigint(0) not null auto_increment,
  4. `content` varchar(255) character set utf8mb4 collate utf8mb4_unicode_ci not null,
  5. `create_date` bigint(0) not null,
  6. `article_id` int(0) not null,
  7. `author_id` bigint(0) not null,
  8. `parent_id` bigint(0) not null,
  9. `to_uid` bigint(0) not null,
  10. `level` varchar(1) character set utf8 collate utf8_general_ci not null,
  11. primary key (`id`) using btree,
  12. index `article_id`(`article_id`) using btree
  13. ) engine = innodb auto_increment = 1405209691876790275 character set = utf8 collate = utf8_general_ci row_format = dynamic;

3.7表七: ms_category类别表

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

4.首页功能

4.1文章列表实现

效果图

 

4.1.1pojo类 

 1.建立pojo类——article

  1. package com.leggasai.dao.pojo;
  2. import lombok.Data;
  3. @Data
  4. public class Article {
  5. public static final int Article_TOP=1;//是否指定,默认是
  6. public static final int Article_Common=0;//默认评论数0
  7. private Long id;//文章id
  8. private String title;//文章标题
  9. private String summary;//文章简介
  10. private Integer commentCounts;//文章评论数
  11. private Integer viewCounts;//文章阅读数
  12. private Long authorId;//作者id
  13. private Long bodyId;//文章内容id
  14. private Long categoryId;//文章类别id
  15. private Integer weight=Article_Common;//文章权重
  16. private Long createDate;//文章创建时间
  17. }

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

  1. package com.leggasai.dao.pojo;
  2. import lombok.Data;
  3. @Data
  4. public class SysUser {
  5. private Long id;//用户id
  6. private String account;//用户账号
  7. private String password;//用户密码
  8. private Integer admin;//是否管理员
  9. private String avatar;//用户头像地址
  10. private Long createDate;//用户创建时间
  11. private Integer deleted;//是否被删除
  12. private String email;//用户邮箱
  13. private Long lastLogin;//用户最后一次登录时间
  14. private String nickname;//用户昵称
  15. private String mobilePhoneNumber;//用户手机号
  16. private String salt;//加密盐
  17. private String status;//用户状态
  18. }

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

  1. package com.leggasai.dao.pojo;
  2. import lombok.Data;
  3. @Data
  4. public class Tag {
  5. private Long id;//标签id
  6. private String avatar;//标签图片地址
  7. private String tagName;//标签名
  8. }

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

  1. import java.util.List;
  2. @Data
  3. public class ArticleVo {
  4. private Long id;
  5. private String title;
  6. private String summary;
  7. private int commentCounts;
  8. private int viewCounts;
  9. private int weight;
  10. /**
  11. * 创建时间
  12. */
  13. private String createDate;
  14. private String author;
  15. private ArticleBodyVo body;
  16. private List<TagVo> tags;
  17. private List<CategoryVo> categorys;
  18. }

4.1.2controller类

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

  1. import java.util.List;
  2. @RestController
  3. @RequestMapping("articles")
  4. public class ArticleController {
  5. @Autowired
  6. private ArticleService articleService;
  7. //Result是统一结果返回
  8. @PostMapping
  9. public Result articles(@RequestBody PageParams pageParams) {
  10. //ArticleVo 页面接收的数据
  11. List<ArticleVo> articles = articleService.listArticlesPage(pageParams);
  12. return Result.success(articles);
  13. }
  14. }

 4.1.3service类

ArticleService接口与ArticleServiceImpl实现类

  1. import java.util.List;
  2. public interface ArticleService {
  3. List<ArticleVo> listArticlesPage(PageParams pageParams);
  4. }
  1. package com.leggasai.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.metadata.IPage;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.leggasai.common.aop.LogAnnotation;
  6. import com.leggasai.dao.dos.Archives;
  7. import com.leggasai.dao.mapper.ArticleBodyMapper;
  8. import com.leggasai.dao.mapper.ArticleMapper;
  9. import com.leggasai.dao.mapper.ArticleTagMapper;
  10. import com.leggasai.dao.pojo.Article;
  11. import com.leggasai.dao.pojo.ArticleBody;
  12. import com.leggasai.dao.pojo.ArticleTag;
  13. import com.leggasai.dao.pojo.SysUser;
  14. import com.leggasai.service.*;
  15. import com.leggasai.utils.UserThreadLocal;
  16. import com.leggasai.vo.ArticleBodyVo;
  17. import com.leggasai.vo.ArticleVo;
  18. import com.leggasai.vo.Result;
  19. import com.leggasai.vo.TagVo;
  20. import com.leggasai.vo.params.ArticleParam;
  21. import com.leggasai.vo.params.PageParams;
  22. import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
  23. import org.joda.time.DateTime;
  24. import org.springframework.beans.BeanUtils;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.stereotype.Service;
  27. import java.util.ArrayList;
  28. import java.util.HashMap;
  29. import java.util.List;
  30. import java.util.Map;
  31. @Service
  32. public class ArticleServiceImpl implements ArticleService {
  33. @Autowired
  34. private ArticleMapper articleMapper;
  35. @Autowired
  36. private SysUserService sysUserService;
  37. @Autowired
  38. private TagsService tagsService;
  39. public ArticleVo copy(Article article,boolean isAuthor,boolean isBody,boolean isTags){
  40. ArticleVo articleVo = new ArticleVo();
  41. BeanUtils.copyProperties(article, articleVo);
  42. if (isAuthor) {
  43. SysUser sysUser = sysUserService.findSysUserById(article.getAuthorId());
  44. articleVo.setAuthor(sysUser.getNickname());
  45. }
  46. articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
  47. if (isTags){
  48. List<TagVo> tags = tagsService.findTagsByArticleId(article.getId());
  49. articleVo.setTags(tags);
  50. }
  51. return articleVo;
  52. }
  53. private List<ArticleVo> copyList(List<Article> records,boolean isAuthor,boolean isBody,boolean isTags) {
  54. List<ArticleVo> articleVoList = new ArrayList<>();
  55. for (Article article : records) {
  56. ArticleVo articleVo = copy(article,isAuthor,isBody,isTags);
  57. articleVoList.add(articleVo);
  58. }
  59. return articleVoList;
  60. }
  61. @Override
  62. public List<ArticleVo> listArticlesPage(PageParams pageParams) {
  63. QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
  64. Page<Article> page = new Page<>(pageParams.getPage(),pageParams.getPageSize());
  65. Page<Article> articlePage = articleMapper.selectPage(page, queryWrapper);
  66. List<ArticleVo> articleVoList = copyList(articlePage.getRecords(),true,false,true);
  67. return articleVoList;
  68. }
  69. }

sysUserService和sysUserServiceImpl 

  1. public interface UserService {
  2. SysUser findUserById(Long userId);
  3. }
  1. package com.leggasai.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.leggasai.dao.mapper.SysUserMapper;
  4. import com.leggasai.dao.pojo.SysUser;
  5. import com.leggasai.service.LoginService;
  6. import com.leggasai.service.SysUserService;
  7. import com.leggasai.vo.ErrorCode;
  8. import com.leggasai.vo.LoginUserVo;
  9. import com.leggasai.vo.Result;
  10. import com.leggasai.vo.UserVo;
  11. import org.apache.commons.lang3.StringUtils;
  12. import org.springframework.beans.BeanUtils;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.data.redis.core.RedisTemplate;
  15. import org.springframework.stereotype.Service;
  16. @Service
  17. public class UserServiceImpl implements UserService {
  18. @Autowired
  19. private SysUserMapper sysUserMapper;
  20. @Override
  21. public SysUser findUserById(Long userId) {
  22. SysUser sysUser = sysUserMapper.selectById(userId);
  23. if (sysUser == null) {
  24. sysUser = new SysUser();
  25. sysUser.setNickname("码神之路");
  26. }
  27. return sysUser;
  28. }
  29. }

tagService和tagServiceImpl 

  1. package com.leggasai.service;
  2. import com.leggasai.vo.Result;
  3. import com.leggasai.vo.TagVo;
  4. import java.util.List;
  5. public interface TagService {
  6. List<TagVo> findTagsByArticleId(Long articleId);
  7. }
  1. package com.leggasai.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.leggasai.dao.mapper.TagMapper;
  4. import com.leggasai.dao.pojo.Tag;
  5. import com.leggasai.service.TagService;
  6. import com.leggasai.vo.Result;
  7. import com.leggasai.vo.TagVo;
  8. import org.springframework.beans.BeanUtils;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Service;
  11. import org.springframework.util.CollectionUtils;
  12. import java.lang.reflect.Array;
  13. import java.util.ArrayList;
  14. import java.util.Collections;
  15. import java.util.List;
  16. @Service
  17. public class TagServiceImpl implements TagService {
  18. @Autowired
  19. private TagMapper tagMapper;
  20. @Override
  21. public List<TagVo> findTagsByArticleId(Long articleId) {
  22. //mybatis-plus无法进行多表查询
  23. List<Tag> tags=tagMapper.findTagsByArticleId(articleId);
  24. return copyList(tags);
  25. }
  26. public TagVo copy(Tag tag){
  27. TagVo tagVo=new TagVo();
  28. BeanUtils.copyProperties(tag,tagVo);
  29. tagVo.setId(String.valueOf(tag.getId()));
  30. return tagVo;
  31. }
  32. public List<TagVo> copyList(List<Tag> tagList){
  33. List<TagVo> tagVoList = new ArrayList<>();
  34. for (Tag tag : tagList) {
  35. tagVoList.add(copy(tag));
  36. }
  37. return tagVoList;
  38. }
  39. }

4.1.4dao层

ArticleMapper接口

  1. package com.leggasai.dao.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.baomidou.mybatisplus.core.metadata.IPage;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.leggasai.dao.dos.Archives;
  6. import com.leggasai.dao.pojo.Article;
  7. import org.apache.ibatis.annotations.Mapper;
  8. import org.springframework.stereotype.Repository;
  9. import java.util.List;
  10. @Mapper
  11. public interface ArticleMapper extends BaseMapper<Article> {
  12. List<Archives> listArchives();
  13. IPage<Article> listArticle(Page<Article> page,
  14. Long categoryId,
  15. Long tagId,
  16. String year,
  17. String month);
  18. }

SysUserMapper接口 

  1. package com.leggasai.dao.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.leggasai.dao.pojo.SysUser;
  4. import org.apache.ibatis.annotations.Mapper;
  5. import org.springframework.stereotype.Repository;
  6. @Mapper
  7. public interface SysUserMapper extends BaseMapper<SysUser> {
  8. }

TagMapper接口 

  1. package com.leggasai.dao.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.leggasai.dao.pojo.Tag;
  4. import org.apache.ibatis.annotations.Mapper;
  5. import org.apache.ibatis.annotations.Param;
  6. import org.springframework.stereotype.Repository;
  7. import java.util.List;
  8. @Mapper
  9. public interface TagMapper extends BaseMapper<Tag> {
  10. /*
  11. 根据文章id查询标签列表
  12. */
  13. List<Tag> findTagsByArticleId(Long articleId);
  14. }

 TagMapper.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!--中文错误改成UTF8即可-->
  3. <!DOCTYPE mapper
  4. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  5. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  6. <mapper namespace="com.leggasai.dao.mapper.TagMapper">
  7. <!-- List<Tag> findTagsByArticleId(Long articleId);-->
  8. <select id="findTagsByArticleId" parameterType="long" resultType="com.leggasai.dao.pojo.Tag">
  9. select id,avatar,tag_name as tagName from ms_tag
  10. where id in (select tag_id from ms_article_tag where article_id=#{articleId})
  11. </select>
  12. </mapper>

4.2首页最热标签功能

 4.2.1前端接口

接口url:/tags/hot

请求方式:GET

请求参数:无

返回数据:

  1. {
  2. "success": true,
  3. "code": 200,
  4. "msg": "success",
  5. "data": [
  6. {
  7. "id":1,
  8. "tagName":"4444"
  9. }
  10. ]
  11. }

4.2.2controller类

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

4.2.3service层

    Result hots(int limit);
  1. @Override
  2. public Result hots(int limit) {
  3. /*
  4. 标签所拥有的文章数量做多,就是最热标签
  5. */
  6. List<Long> tagIds=tagMapper.findHotsTagIds(limit);
  7. if(CollectionUtils.isEmpty(tagIds)){
  8. return Result.success(Collections.emptyList());
  9. }
  10. //需要的是tagId和tagName
  11. List<Tag> tagList=tagMapper.findTagesByTagIds(tagIds);
  12. //System.out.println("最热标签");
  13. //System.out.println(tagList);
  14. return Result.success(tagList);
  15. }

4.2.4mapper层

  1. <select id="findHotsTagIds" parameterType="int" resultType="java.lang.Long">
  2. select tag_id from ms_article_tag group by tag_id order by COUNT(*) desc limit #{limit}
  3. </select>
  4. <select id="findTagesByTagIds" parameterType="list" resultType="com.leggasai.dao.pojo.Tag">
  5. select id,tag_name as tagName from ms_tag
  6. where id in
  7. <foreach collection="tagIds" item="tagId" separator="," open="(" close=")">
  8. #{tagId}
  9. </foreach>
  10. </select>

4.3首页最热文章功能

 

后续可以用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层

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

4.3.3service层

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

4.4首页最新文章功能

 

后续可以用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层

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

4.4.3service层

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

4.5首页文章归档功能

 

4.5.1前端接口

接口url:/articles/listArchives

请求方式:POST

请求参数:

返回数据:

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

}

4.5.2controller层

  1. @PostMapping("listArchives")
  2. public Result listArchives(){
  3. return articleService.listArchives();
  4. }

4.5.3service层

  1. @Override
  2. public Result listArchives() {
  3. List<Archives> archivesList=articleMapper.listArchives();
  4. return Result.success(archivesList);
  5. }

4.5.4mapper层 

    List<Archives> listArchives();

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

  1. <select id="listArchives" resultType="com.leggasai.dao.dos.Archives">
  2. select FROM_UNIXTIME(create_date/1000,'%Y') as year,FROM_UNIXTIME(create_date/1000,'%m') as month,COUNT(*) as COUNT
  3. from ms_article group by year,month
  4. </select>

 Archives类

  1. package com.leggasai.dao.dos;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class Archives {
  9. private Integer year;
  10. private Integer month;
  11. private Long count;
  12. }

5.登录功能

5.1jwt技术

5.2退出功能

5.3注册功能

5.4登录拦截器

5.5ThreadLocal使用

未完待续~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/84761
推荐阅读
相关标签
  

闽ICP备14008679号