1.前置条件
jdk | 1.8 |
MySQL | 8.0.26 |
Maven | 3.6.3 |
1.1技术栈
SpringBoot 、MyBatisplus、MySQL、redis
2.工程搭建
2.1创建空maven项目
2.2 创建子模块(maven)
2.3导入父工程依赖
删除src文件
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
<artifactId>springboot_blog</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>buka_framework</module>
<module>buka_admin</module>
<module>buka_blog</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<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>S{java.version]</target>
<encoding>S{project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.4buka_admin依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>springboot_blog</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>buka_admin</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>buka_framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2.5buka_blog依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>springboot_blog</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>buka_blog</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>buka_framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
2.6buka_framework依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>springboot_blog</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>buka_framework</artifactId>
<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>
<version>1.2.33</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
3.配置
3.1数据库表的导入
3.2配置及启动类
server:
port: 7777
spring:
datasource:
url: jdbc:mysql://localhost:3306/blog?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
multipart:
max-file-size: 2MB
max-request-size: 5MB
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
package com.buka;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
//@MapperScan("com.buka.mapper")
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class,args);
}
}
运行测试正常启动显示7777端口
4.安装插件
安装MybatisX进行代码生成
数据库登录
选中所有表右键选择插件
图中
图中勾选
生成后
5.完善子模块framework
5.1分装结果集
创建枚举enums包
package com.buka.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;
}
}
创建util包
package com.buka.util;
import com.buka.enums.AppHttpCodeEnum;
import java.io.Serializable;
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;
}
}
5.2前后端分离的跨域问题
创建config包
package com.buka.config;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
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);
}
}
5.3vo
vo包 constant包
package com.buka.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HotArticleVo {
private Long id;
private String title;
private Long viewCount;
}
package com.buka.constant;
public class SystemConstants {
public static final int ARTICLE_STATUS_DRAFT = 1;
public static final int ARTICLE_STATUS_NORMAL = 0;
}
package com.buka.util;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
public class BeanCopyUtil {
private BeanCopyUtil() {
}
public static <V> V copyBean(Object source, Class<V> clazz) {
V result = null;
try {
result = clazz.newInstance();
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());
}
}
5.4service 以及Impl实现类
增加展示热门文章方法
package com.buka.service;
import com.buka.util.ResponseResult;
import com.buka.entity.Article;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表【article(文章表)】的数据库操作Service
* @createDate 2023-11-15 13:35:49
*/
public interface ArticleService extends IService<Article> {
ResponseResult hotArticleList();
}
实现类增加分页、拷贝、字面值处理功能
package com.buka.service.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.buka.constant.SystemConstants;
import com.buka.util.ResponseResult;
import com.buka.entity.Article;
import com.buka.service.ArticleService;
import com.buka.mapper.ArticleMapper;
import com.buka.vo.HotArticleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author 11412
* @description 针对表【article(文章表)】的数据库操作Service实现
* @createDate 2023-11-15 13:27:57
*/
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article>
implements ArticleService {
@Override
public ResponseResult hotArticleList() {
LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
lambdaQueryWrapper.orderByDesc(Article::getViewCount);
lambdaQueryWrapper.last("limit 0,10");
Page<Article> page = new Page<>(1, 10);
page(page, lambdaQueryWrapper);
List<Article> articles = page.getRecords();
List<HotArticleVo> articleVos = new ArrayList<>();
for (Article article : articles) {
HotArticleVo vo = new HotArticleVo();
BeanUtils.copyProperties(article, vo);
articleVos.add(vo);
}
return ResponseResult.okResult(articleVos);
}
}
6.blog中编写cntroller运行测试
package com.buka.controller;
import com.buka.util.ResponseResult;
import com.buka.service.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;
@RestController
@RequestMapping("/article")
public class ArticleController {
@Autowired
private ArticleService articleService;
@GetMapping("/hotArticleList")
public ResponseResult hotArticleList(){
ResponseResult result=articleService.hotArticleList();
return result;
}
}
6.1运行遇到的bug
(1)bean注入问题
启动类BlogApplication加
@MapperScan("com.buka.mapper")扫描mapper或在所有mapper类加@Mapper注解
(2)表多主键问题
将@TableId注解指定的主键都注释(仅ArticleTag表具有双主键)
测试
正常启动 打印出数据