简介

本项目主要参考 B站 up 主三更的视频

B站最通俗易懂手把手SpringBoot+Vue项目实战-前后端分离博客项目-Java项目 | 三更草堂 | 哔哩哔哩

工程创建

  • IDEA > File > New > Project > Maven ArcheType
1
2
3
4
5
6
7
8
9
10
Name: JavaProject
Location: ~\Desktop\code\Java
JDK: 1.8
Catalog: Internal
Archetype: org.apache.maven.archetypes:maven-archetype-quickstart
version: 1.0
// Advanced Settings
GroupId: com.wenxiang
ArtifactId: JavaProject
version: 1.0-SNAPSHOT
  • 配置根目录下的 pom.xml 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.wenxiang</groupId>
<artifactId>JavaProject</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<name>JavaProject</name>
<url>http://maven.apache.org</url>
<modules>
<module>PublicFramework</module>
</modules>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<dependencyManagement>
<dependencies>
<!--Spring Boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>

<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>

<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>

<!--阿里云oss-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>

<!--easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>

<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>

<!--swagger-ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

多模块开发

  • 公共模块 PublicFramework
  • 后台管理模块 AdminFramework
  • 前台使用模块 UserFramework

第一个子模块-公共依赖

  • 右键项目根目录 > New > Module > Maven ArcheType
1
2
3
4
5
6
7
8
9
10
11
Name: PublicFramework
Location: ~\Desktop\code\Java\JavaProject
JDK: 1.8
Parent: JavaProject
Catalog: Internal
Archetype: org.apache.maven.archetypes:maven-archetype-quickstart
version: 1.1
// Advanced Settings
GroupId: com.wenxiang
ArtifactId: PublicFramework
version: 1.0-SNAPSHOT
  • 配置 pom.xml 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>

手动下载 jar 包
以 springfox-swagger2 为例, 在 maven repo 仓库中找到对应的版本 io/springfox/springfox-swagger2/2.9.2, 下载 .jar, .jar.sha1, .pom, .pom.sha1 为后缀的四个文件, 将其放到 maven 本地仓库对应的目录下.

UserFramework > src > main > resource > application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server:
port: 7777
spring:
# 数据库相关配置
datasource:
url: jdbc:mysql://localhost:3306/blog?characterEncoding=utf-8
username: root
password: "162670"
driver-class-name: com.mysql.cj.jdbc.Driver
# 文件上传配置
servlet:
multipart:
max-file-size: 2MB
max-request-size: 5MB
# mybatis-plus 配置
mybatis-plus:
configuration:
# 日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
# 逻辑删除字段
db-config:
logic-delete-field: delFlag
logic-delete-value: 1
logic-not-delete-value: 0
id-type: auto

第二个子模块-后台管理

  • 右键项目根目录 > New > Module > Maven ArcheType
1
2
3
4
5
6
7
8
9
10
11
Name: AdminFramework
Location: ~\Desktop\code\Java\JavaProject
JDK: 1.8
Parent: JavaProject
Catalog: Internal
Archetype: org.apache.maven.archetypes:maven-archetype-quickstart
version: 1.1
// Advanced Settings
GroupId: com.wenxiang
ArtifactId: AdminFramework
version: 1.0-SNAPSHOT
  • 配置 pom.xml 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.wenxiang</groupId>
<artifactId>JavaProject</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>AdminFramework</artifactId>
<packaging>jar</packaging>

<name>AdminFramework</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!--直接依赖PublicFramework的依赖-->
<dependency>
<groupId>com.wenxiang</groupId>
<artifactId>PublicFramework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

第三个子模块-前台用户

  • 右键项目根目录 > New > Module > Maven ArcheType
1
2
3
4
5
6
7
8
9
10
11
Name: UserFramework
Location: ~\Desktop\code\Java\JavaProject
JDK: 1.8
Parent: JavaProject
Catalog: Internal
Archetype: org.apache.maven.archetypes:maven-archetype-quickstart
version: 1.1
// Advanced Settings
GroupId: com.wenxiang
ArtifactId: UserFramework
version: 1.0-SNAPSHOT
  • 配置 pom.xml 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.wenxiang</groupId>
<artifactId>JavaProject</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>UserFramework</artifactId>
<packaging>jar</packaging>

<name>UserFramework</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!--直接依赖PublicFramework的依赖-->
<dependency>
<groupId>com.wenxiang</groupId>
<artifactId>PublicFramework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

数据库

  • 执行数据库脚本

  • 连接数据库
    IDEA侧栏 > DataBase > New > Data Source > MySQL
    填写用户名, 密码, 名字

    初次使用会提示安装组件

  • 安装 Easy Code 插件
    IDEA > File > Settings > Plugins > Easycode

  • 配置 Easy Code 模板

    IDEA > File > Settings > EasyCode > Template > Group Name: MybatisPlus > entity.java.vm

    修改后的模板如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    ##导入宏定义
    $!{define.vm}

    ##保存文件(宏定义)
    #save("/entity", ".java")

    ##包路径(宏定义)
    #setPackageSuffix("entity")

    ##自动导入包(全局变量)
    $!{autoImport.vm}
    import java.io.Serializable;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;

    ##表注释(宏定义)
    #tableComment("表实体类")
    @SuppressWarnings("serial")
    @AllArgsConstructor
    @Data
    @NoArgsConstructor
    public class $!{tableInfo.name} {
    #foreach($column in $tableInfo.fullColumn)
    #if(${column.comment})//${column.comment}#end

    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
    #end
    }

    点击右上角的实时调试可以来查看修改后的效果

  • 导入数据库中的表
    IDEA侧栏 > DataBase > blog > schemas > 右键article > EasyCode > Generate Code

    Easy Code Title Info

创建实体类 Mapper 和 service

在 ==PublicFramework== > ··· > com.wenxinag 下创建 domain 包, 将整个 entity 移入 domain 下

同时在 com.wenxiang 下创建 Mapper 包 和 service 包

在 Mapper 下新建 Java Class 命名 ArticleMapper

1
2
3
4
5
6
7
8
package com.wenxiang.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wenxiang.domain.entity.Article;

public interface ArticleMapper extends BaseMapper<Article> {

}

在 service 下新建 Java Class 命名 ArticleService

1
2
3
4
5
6
7
8
package com.wenxiang.sevice;

import com.baomidou.mybatisplus.extension.service.IService;
import com.wenxiang.domain.entity.Article;

public interface ArticleService extends IService<Article> {

}

在 service 下新建 Java Class 命名 impl.ArticleServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
package com.wenxiang.sevice.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.mapper.ArticleMapper;
import com.wenxiang.sevice.ArticleService;
import org.springframework.stereotype.Service;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

}

创建 controller

在 ==UserFramework== > ··· > com.wenxinag 下创建 controller 包
在 controller 包下新建 Java Class, 命名 ArticleController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.wenxiang.controller;

import com.wenxiang.domain.entity.Article;
import com.wenxiang.sevice.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/article")
public class ArticleController {

@Autowired
private ArticleService articleService;

@GetMapping("/list")
public List<Article> test(){
return articleService.list();
}
}

此时切到 UserFramework 下的 BlogApplication, 点击 Run, 报错如下

1
Error creating bean with name 'articleController': Unsatisfied dependency expressed through field 'articleService'; ...

这是由于 UserFramework 对 PublicFramework 模块的依赖还停留在老版本, 于是 PublicFramework 下新建的新建的类就没有出现在 UserFramework 的依赖中
处理方法是在 Maven 中, 选择父工程, JavaProject > Lifecycle > 双击install, 重新打包依赖

  • 关于 Cannot resolve symbol junit 报错
    是由于此前在 pom.xml 中注释掉了关于 junit 的依赖

    1
    2
    3
    4
    5
    6
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
    </dependency>

第二次运行 BlogApplication.java 报错, 此时需要添加

1
2
3
4
5
...
@MapperScan("com.wenxiang.mapper") //添加映射
public class BlogApplication {
...
}

此时运行成功.
在浏览器地址栏中输入 localhost:7777/article/list, 并没有出现 article, 而是加载出登录页面, 这是由于项目依赖了 spring-boot-starter-security 造成的.
当前为了方便测试, 暂时将 PublicFramework 下 pom.xml 中关于 spring-boot-starter-security 的依赖注释掉.

1
2
3
4
<!--        <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->

注释之后需要先更新 Maven, 然后由于修改了 PublicFramework 所以需要再次 Maven > JavaProject (root) > Lifecycle > 双击install, 重新打包

打包完成后重启项目, 浏览器访问 localhost:7777/article/list, 再次报错
报错状态为 500, Console 中给出的报错信息为 Access denied for user 'root'@'localhost' (using password: YES), 排查为 UserFramework > src > main > resource > application.yml 中关于数据库的配置有问题, 修改 password 字段

1
2
3
4
5
6
7
8
9
server:
port: 7777
spring:
# 数据库相关配置
datasource:
url: jdbc:mysql://localhost:3306/blog?characterEncoding=utf-8
username: root
password: "162670" #记得加上双引号
driver-class-name: com.mysql.cj.jdbc.Driver

重新运行, 刷新浏览器页面, 正常显示出 article 中的内容.

课程中出现的一个报错: Table 'sg_blog.article' doesn't exist
这是由于课程中示例的数据库 sg_blog 中的表单名称为 sg_article, 但是对应的实体类名称为 Article, 再没有额外指明的情况下, Java 默认认为数据的名称和实体类的名称一致, 所以去 sg_blog 数据库下查询 article 表单而没有找到, 所以返回上述信息.
解决办法: 在 PublicFramework/src/main/java/com/wenxiang/domain/entity/Article.java 实体类中添加一个注解, 让其和数据库表单的名称对应起来, 如下

1
2
3
4
5
6
7
8
...
@TableName("数据库对应的表单名称") //添加 TableName 注解, 将数据库表单的名称和实体类建立映射
public class Article {

@TableId //添加 TableId 注解
private Long id;
...
}

而我在实际操作的时候, 数据库表单名称 article (没有 sg_ 前缀)和实体类名称 Article 是一致的, 所以没有报这个错误.

热门文章列表

Note: 在项目目录上栏右侧的 Options > Tree Appearance > 取消勾选 Compact Middle Packges 可以展开连在一起的 Package

准备工作

  • 右键 PublicFramework/src/main/java/com/wenxiang/domain 目录, 粘贴下面的代码, IDEA 将直接创建一个 Java Class 类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package com.wenxiang.domain;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.wenxiang.enums.AppHttpCodeEnum;

import java.io.Serializable;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> implements Serializable {
private Integer code;
private String msg;
private T data;

public ResponseResult() {
this.code = AppHttpCodeEnum.SUCCESS.getCode();
this.msg = AppHttpCodeEnum.SUCCESS.getMsg();
}

public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}

public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}

public ResponseResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}

public static ResponseResult errorResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.error(code, msg);
}
public static ResponseResult okResult() {
ResponseResult result = new ResponseResult();
return result;
}
public static ResponseResult okResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.ok(code, null, msg);
}

public static ResponseResult okResult(Object data) {
ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getMsg());
if(data!=null) {
result.setData(data);
}
return result;
}

public static ResponseResult errorResult(AppHttpCodeEnum enums){
return setAppHttpCodeEnum(enums,enums.getMsg());
}

public static ResponseResult errorResult(AppHttpCodeEnum enums, String msg){
return setAppHttpCodeEnum(enums,msg);
}

public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
return okResult(enums.getCode(),enums.getMsg());
}

private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String msg){
return okResult(enums.getCode(),msg);
}

public ResponseResult<?> error(Integer code, String msg) {
this.code = code;
this.msg = msg;
return this;
}

public ResponseResult<?> ok(Integer code, T data) {
this.code = code;
this.data = data;
return this;
}

public ResponseResult<?> ok(Integer code, T data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
return this;
}

public ResponseResult<?> ok(T data) {
this.data = data;
return this;
}

public Integer getCode() {
return code;
}

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

public String getMsg() {
return msg;
}

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

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

}
  • 在 PublicFramework/src/main/java/com/wenxiang 目录下创建 Package 命名为 enums, 右键 enums 粘贴下面的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.wenxiang.enums;

public enum AppHttpCodeEnum {
// 成功
SUCCESS(200,"操作成功"),
// 登录
NEED_LOGIN(401,"需要登录后操作"),
NO_OPERATOR_AUTH(403,"无权限操作"),
SYSTEM_ERROR(500,"出现错误"),
USERNAME_EXIST(501,"用户名已存在"),
PHONENUMBER_EXIST(502,"手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"),
REQUIRE_USERNAME(504, "必需填写用户名"),
LOGIN_ERROR(505,"用户名或密码错误");
int code;
String msg;

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

public int getCode() {
return code;
}

public String getMsg() {
return msg;
}
}

代码实现

  • UserFramework/src/main/java/com/wenxiang/controller/ArticleController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.wenxiang.controller;

import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.sevice.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/article")
public class ArticleController {

@Autowired
private ArticleService articleService;

// @GetMapping("/list")
// public List<Article> test(){
// return articleService.list();
// }

@GetMapping("/hotArticleList")
public ResponseResult hotArticleList(){

ResponseResult result = articleService.hotArticleList();
return result;
}
}
  • PublicFramework/src/main/java/com/wenxiang/sevice/ArticleService.java
1
2
3
4
5
6
7
8
9
10
package com.wenxiang.sevice;

import com.baomidou.mybatisplus.extension.service.IService;
import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Article;

public interface ArticleService extends IService<Article> {

ResponseResult hotArticleList();
}
  • PublicFramework/com/wenxiang/sevice/impl/ArticleServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.wenxiang.sevice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.mapper.ArticleMapper;
import com.wenxiang.sevice.ArticleService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

@Override
public ResponseResult hotArticleList() {
//查询热门文章, 封装成 ResponseResult 并返回
LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
//必须是正式文章
queryWrapper.eq(Article::getStatus, 0);
//按照浏览量进行排序
queryWrapper.orderByDesc(Article::getViewCount);
//最多之查询10条
Page<Article> page = new Page(1, 10);
page(page, queryWrapper);

List<Article> articles = page.getRecords();
return ResponseResult.okResult(articles);
}
}
  • Postman 测试
    Run BlogApplication.java, 正常运行
    在 Postman Desktop 中使用 GET 访问 http://localhost:7777/article/hotArticleList

    Note: 使用 Postman Desktop 版本进行测试, 使用网页版不能正确得到 Response, 给出下面提示:
    Could not send request
    Cloud Agent Error: Can not send requests to localhost. Select a different agent. | Use Postman's Desktop Agent

前端工程联调

安装依赖和启动

切到前端工程 blog-vue 目录下, 调出 cmd

1
2
3
4
5
# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

直接只用 npm install 报错, 请按照下面步骤使用 cnpm 安装依赖

  • 清除缓存

    1
    npm cache clean --force
  • 删除项目中的 node_modules 文件夹

  • 安装 cnpm

    1
    npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 用 cnpm 安装依赖

    1
    cnpm install 

测试联调

解决跨域访问问题

PublicFramework/src/main/java/com/wenxiang/ 下新建 config 包, 右键粘贴下面代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.wenxiang.config;

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 WebConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOriginPatterns("*")
// 是否允许cookie
.allowCredentials(true)
// 设置允许的请求方式
.allowedMethods("GET", "POST", "DELETE", "PUT")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
}

Maven 下重新 install 整个项目, 重启项目. 此时刷新前端页面, 可以看到 “热门文章” 栏.
可以 F12 (或者鼠标右键>检查) 调出开发者工具, 切换到 Network, 点击页面地址栏左边的刷新, 筛选选择 Fetch/XHR, 可以看到 hotArticleList, 点击 Preview 可以看到返回的信息.

VO 优化

VO 即 View Object

在 PublicFramework/src/main/java/com/wenxiang/domain 目录下新建 Package 命名为 vo, 在 vo 下新建 Java Class 命名为 HotArticleVo

  • PublicFramework/src/main/java/com/wenxiang/domain/vo/HotArticleVo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.wenxiang.domain.vo;

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

@Data
@NoArgsConstructor
@AllArgsConstructor
public class HotArticleVo {
private Long id;
//标题
private String title;
//访问量
private String viewCount;
}
  • PublicFramework/src/main/java/com/wenxiang/sevice/impl/ArticleServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.wenxiang.sevice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.domain.vo.HotArticleVo;
import com.wenxiang.mapper.ArticleMapper;
import com.wenxiang.sevice.ArticleService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

@Override
public ResponseResult hotArticleList() {
//查询热门文章, 封装成 ResponseResult 并返回
LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
//必须是正式文章
queryWrapper.eq(Article::getStatus, 0);
//按照浏览量进行排序
queryWrapper.orderByDesc(Article::getViewCount);
//最多之查询10条
Page<Article> page = new Page(1, 10);
page(page, queryWrapper);

List<Article> articles = page.getRecords();

// Bean 拷贝
List<HotArticleVo> articleVos = new ArrayList<>();
for (Article article : articles) {
HotArticleVo vo = new HotArticleVo();
BeanUtils.copyProperties(article, vo);
articleVos.add(vo);
}

return ResponseResult.okResult(articleVos);
}
}

字面量处理

PublicFramework/src/main/java/com/wenxiang/constants/SystemConstants.java

1
2
3
4
5
6
7
8
9
10
11
12
public class SystemConstants
{
/**
* 文章是草稿
*/
public static final int ARTICLE_STATUS_DRAFT = 1;
/**
* 文章是正常分布状态
*/
public static final int ARTICLE_STATUS_NORMAL = 0;

}

将 PublicFramework/src/main/java/com/wenxiang/sevice/impl/ArticleServiceImpl.java 中的 0 修改为 SystemConstants.ARTICLE_STATUS_NORMAL

1
2
3
4
5
6
7
8
...
@Override
public ResponseResult hotArticleList() {
...
queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
...
}
...

Bean 拷贝工具类封装

PublicFramework\src\main\java\com\wenxiang\utils\BeanCopyUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.wenxiang.utils;

import com.wenxiang.constants.SystemConstants;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.domain.vo.HotArticleVo;
import org.springframework.beans.BeanUtils;

import java.sql.SQLOutput;
import java.util.List;
import java.util.stream.Collectors;

public class BeanCopyUtils {

private BeanCopyUtils(){

}

public static <V> V copyBean(Object source, Class<V> clazz) {
// 创建目标对象
V result = null;
try {
result = clazz.newInstance();
// 实现属性 Copy
BeanUtils.copyProperties(source, result);

} catch (Exception e) {
e.printStackTrace();
}

// 返回结果
return result;
}

public static <O, V> List<V> copyBeanList(List<O> list, Class<V> clazz){
return list.stream()
.map(o -> copyBean(o, clazz))
.collect(Collectors.toList());
}

public static void main(String[] args){
Article article = new Article();
article.setId(1L);
article.setTitle("ss");

HotArticleVo hotArticleVo = copyBean(article, HotArticleVo.class);
System.out.println(hotArticleVo);

}
}

PublicFramework\src\main\java\com\wenxiang\sevice\impl\ArticleServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.wenxiang.sevice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.wenxiang.constants.SystemConstants;
import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.domain.vo.HotArticleVo;
import com.wenxiang.mapper.ArticleMapper;
import com.wenxiang.sevice.ArticleService;
import com.wenxiang.utils.BeanCopyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

@Override
public ResponseResult hotArticleList() {
//查询热门文章, 封装成 ResponseResult 并返回
LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
//必须是正式文章
queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
//按照浏览量进行排序
queryWrapper.orderByDesc(Article::getViewCount);
//最多之查询10条
Page<Article> page = new Page(1, 10);
page(page, queryWrapper);

List<Article> articles = page.getRecords();

// // Bean 拷贝
// List<HotArticleVo> articleVos = new ArrayList<>();
// for (Article article : articles) {
// HotArticleVo vo = new HotArticleVo();
// BeanUtils.copyProperties(article, vo);
// articleVos.add(vo);
// }

List<HotArticleVo> vs = BeanCopyUtils.copyBeanList(articles, HotArticleVo.class);

return ResponseResult.okResult(vs);
}
}

分类列表查询

EasyCode 代码模板

  • IDEA > File > Settings > EasyCode > Template > Group Name: MybatisPlus > entity.java.vm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
##导入宏定义
$!{define.vm}

##保存文件(宏定义)
#save("/entity", ".java")

##包路径(宏定义)
#setPackageSuffix("entity")

##自动导入包(全局变量)
$!{autoImport.vm}

import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
##表注释(宏定义)
#tableComment("表实体类")
@SuppressWarnings("serial")
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("$!{tableInfo.obj.name}")
public class $!{tableInfo.name} {
#foreach($column in $tableInfo.pkColumn)
#if(${column.comment})//${column.comment}#end
@TableId
private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.otherColumn)
#if(${column.comment})//${column.comment}#end

private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}
  • IDEA > File > Settings > EasyCode > Template > Group Name: MybatisPlus > dao.java.vm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
##导入宏定义
$!{define.vm}

##设置表后缀(宏定义)
#setTableSuffix("Mapper")

##保存文件(宏定义)
#save("/mapper", "Mapper.java")

##包路径(宏定义)
#setPackageSuffix("mapper")

import com.baomidou.mybatisplus.core.mapper.BaseMapper;


##表注释(宏定义)
#tableComment("表数据库访问层")
public interface $!{tableName} extends BaseMapper<$!tableInfo.name> {

}
  • IDEA > File > Settings > EasyCode > Template > Group Name: MybatisPlus > service.java.vm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
##导入宏定义
$!{define.vm}

##设置表后缀(宏定义)
#setTableSuffix("Service")

##保存文件(宏定义)
#save("/service", "Service.java")

##包路径(宏定义)
#setPackageSuffix("service")

import com.baomidou.mybatisplus.extension.service.IService;


##表注释(宏定义)
#tableComment("表服务接口")
public interface $!{tableName} extends IService<$!tableInfo.name> {

}
  • IDEA > File > Settings > EasyCode > Template > Group Name: MybatisPlus > serviceImpl.java.vm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
##导入宏定义
$!{define.vm}

##设置表后缀(宏定义)
#setTableSuffix("ServiceImpl")

##保存文件(宏定义)
#save("/service/impl", "ServiceImpl.java")

##包路径(宏定义)
#setPackageSuffix("service.impl")

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

##表注释(宏定义)
#tableComment("表服务实现类")
@Service("$!tool.firstLowerCase($tableInfo.name)Service")
public class $!{tableName} extends ServiceImpl<$!{tableInfo.name}Mapper, $!{tableInfo.name}> implements $!{tableInfo.name}Service {

}

IDEA侧栏 > DataBase > blog > schemas > 右键category > EasyCode > Generate Code

Easy Code

这个是直接在 java 目录下创建的, 要将 mapper, entity, service 和 serviceImpl 分别移入到各自的目录下

分类列表代码实现

  • UserFramework\src\main\java\com\wenxiang\controller\CategoryController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.wenxiang.controller;

import com.wenxiang.domain.ResponseResult;
import com.wenxiang.sevice.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/category")
public class CategoryController {

@Autowired
private CategoryService categoryService;

@GetMapping("/getCategoryList")
public ResponseResult getCategoryList(){
return categoryService.getCategoryList();
}
}
  • PublicFramework\src\main\java\com\wenxiang\sevice\CategoryService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.wenxiang.sevice;

import com.baomidou.mybatisplus.extension.service.IService;
import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Category;


/**
* 分类表(Category)表服务接口
*
* @author makejava
* @since 2023-05-28 21:22:01
*/
public interface CategoryService extends IService<Category> {

ResponseResult getCategoryList();
}
  • PublicFramework\src\main\java\com\wenxiang\sevice\impl\CategoryServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.wenxiang.sevice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenxiang.constants.SystemConstants;
import com.wenxiang.domain.ResponseResult;
import com.wenxiang.domain.entity.Article;
import com.wenxiang.domain.entity.Category;
import com.wenxiang.domain.vo.CategoryVo;
import com.wenxiang.mapper.CategoryMapper;
import com.wenxiang.sevice.ArticleService;
import com.wenxiang.sevice.CategoryService;
import com.wenxiang.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* 分类表(Category)表服务实现类
*
* @author makejava
* @since 2023-05-28 21:22:02
*/
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

@Autowired
private ArticleService articleService;

@Override
public ResponseResult getCategoryList() {
//查询文章表, 状态为已发布的文章
LambdaQueryWrapper<Article> articleWrapper = new LambdaQueryWrapper<>();
articleWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
List<Article> articleList = articleService.list(articleWrapper);

//获取文章的分类id, 并且去重
Set<Long> categoryIds = articleList.stream()
.map(article -> article.getCategoryId())
.collect(Collectors.toSet());

//查询分类表
List<Category> categories = listByIds(categoryIds);

categories = categories.stream()
.filter(category -> SystemConstants.STATUS_NORMAL.equals(category.getStatus()))
.collect(Collectors.toList());

//封装vo
List<CategoryVo> categoryVos = BeanCopyUtils.copyBeanList(categories, CategoryVo.class);

return ResponseResult.okResult(categoryVos);
}
}
  • PublicFramework\src\main\java\com\wenxiang\domain\vo\CategoryVo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.wenxiang.domain.vo;

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

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CategoryVo {

private Long id;
private String name;

}
  • PublicFramework\src\main\java\com\wenxiang\constants\SystemConstants.java 中添加常量
1
public static final String STATUS_NORMAL = "0";

查询文章列表

查询文章列表代码实现

  • UserFramework\src\main\java\com\wenxiang\controller\ArticleController.java 中添加 articleList 方法
1
2
3
4
5
6
7
8
9
10
11
12
...
@RestController
@RequestMapping("/article")
public class ArticleController {

...

@GetMapping("/articleList")
public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId){
return articleService.articleList(pageNum, pageSize, categoryId);
}
}

articleList 的具体实现是在 articleService 中实现的

Note: 光标放到标红的 articleList 上 Alt+Enter,
Create method 'articleList' in 'ArticleService' + Enter
可以快速在 ArticleService 中创建该方法

  • PublicFramework\src\main\java\com\wenxiang\sevice\ArticleService.java
1
2
3
4
5
6
7
...
public interface ArticleService extends IService<Article> {

...

ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId);
}

Note: Alt+Ctrl+鼠标左键点击 ArticleService 可以快速跳转到实现类 ArticleServiceImpl

  • PublicFramework\src\main\java\com\wenxiang\sevice\impl\ArticleServiceImpl.java

Note: 光标放到标红色波浪线的地方 Alt+Enter > Implement methods + Enter > articleList(…) + Enter 可以快速在 ArticleServiceImpl 中创建 articleList() 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

...

@Override
public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
//查询条件
LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();

//如果有 categoryId 就要 查询时和传入的相同
lambdaQueryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0, Article::getCategoryId, categoryId);

//状态是正式发布的
lambdaQueryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);

//对 isTop 进行降序排序
lambdaQueryWrapper.orderByDesc(Article::getIsTop);


//分页查询
Page<Article> page = new Page<>(pageNum, pageSize);
page(page, lambdaQueryWrapper);

//封装查询结果
List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVo.class);

PageVo pageVo = new PageVo(articleListVos, page.getTotal());
return ResponseResult.okResult(pageVo);
}
}
  • PublicFramework\src\main\java\com\wenxiang\domain\vo\ArticleListVo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.wenxiang.domain.vo;

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

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ArticleListVo {

private Long id;
//标题
private String title;
//文章内容
private String content;
//文章摘要
private String summary;
//所属分类名
private Long categoryName;
//缩略图
private String thumbnail;
//访问量
private Long viewCount;
private Date createTime;
}
  • PublicFramework\src\main\java\com\wenxiang\domain\vo\PageVo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.wenxiang.domain.vo;

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

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageVo {
private List rows;
private Long total;
}
  • Postman 测试

http://localhost:7777/article/articleList

报错, 返回状态码 500

1
2
3
4
5
6
{
"timestamp": "2023-05-29T03:39:38.178+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/article/articleList"
}

传入参数

传入参数

MybatisPlus 分页支持配置
PublicFramework\src\main\java\com\wenxiang\config\MbatisPlusConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class MbatisPlusConfig {

/**
* 3.4.0之后版本
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}

配置完成后重新 install, Postman 中再次检测, 分页正常

分页正常

分类名称问题解决-普通循环方式

  • 添加 categoryName 字段, 并且要加上注释
    PublicFramework\src\main\java\com\wenxiang\domain\entity\Article.java

    1
    2
    3
    4
    5
    6
    7
    ...
    public class Article {
    ...
    @TableField(exist = false) //注释
    private String categoryName;
    ...
    }
  • 主体代码
    PublicFramework\src\main\java\com\wenxiang\sevice\impl\ArticleServiceImpl.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ...
    @Service
    public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    ...
    @Override
    public ResponseResult articleList(...) {
    ...
    //分页查询
    ...
    //查询categoryName
    List<Article> articles = page.getRecords();
    //articleId去查询articleName进行设置
    for (Article article : articles) {
    Category category = categoryService.getById(article.getCategoryId());
    article.setCategoryName(category.getName());
    }
    //封装查询结果
    ...
    }
    }
  • 测试没有正常显示 categoryName 字段, 修改 categoryName 的属性为 String 类型
    PublicFramework\src\main\java\com\wenxiang\domain\vo\ArticleListVo.java

    1
    2
    3
    4
    5
    6
    7
    8
    ...
    public class ArticleListVo {
    ...
    //所属分类名
    // private Long categoryName;
    private String categoryName;
    ...
    }
  • 再次测试, 成功

    http://localhost:7777/article/articleList?pageNum=1&pageSize=10&categoryId=1

    categoryName

分类名称问题解决-Stream流

PublicFramework\src\main\java\com\wenxiang\sevice\impl\ArticleServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

...

@Override
public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
...
List<Article> articles = page.getRecords();
//查询categoryName
articles.stream()
.map(article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
.collect(Collectors.toList());

//封装查询结果
...
}
}