spring boot 练手实战项目说明
码神之路网站所使用的博客,项目简单,需求明确,容易上手,非常适合做为练手级项目。
最终成品
项目讲解说明:
提供前端工程,只需要实现后端接口即可
项目以单体架构入手,先快速开发,不考虑项目优化,降低开发负担
开发完成后,开始优化项目,提升编程思维能力
比如页面静态化,缓存,云存储,日志等
docker部署上线
云服务器购买,域名购买,域名备案等
项目使用技术 :
springboot + mybatisplus+redis+mysql
基础知识
Spring常用注解,注解 IOC ,AOP,MVC 的理解
mybatisDao层 Mapper层 controller层 service层 model层 entity层 简介
mall商场学习文档
mybatisplus学习文档
mybatisplus配套代码
easycode搭配mybatisplus巨爽
@Autowired 的时候为什么注入接口不是实现类
@Service注解为什么是标注在实现类上的
mapper接口需要加注解吗?通过MapperScan减少注解
@Mapper与@MapperScan注解的作用是什么?
工程搭建
前端的工程:
npm install
npm run build
npm run dev
新建Maven工程
<?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>com.mszlu</groupId>
<artifactId>blog-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.0</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<!-- 排除 默认使用的logback -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application配置文件配置
server.port=8888
spring.application.name=komorebi_blog
#数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=747699
#mybatis
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#标识表名均为ms_前缀,后续操作可以不用定义这个前缀
mybatis-plus.global-config.db-config.table-prefix=ms_
MybatisPlus配置
创建配置类,设置分页查询(一般项目都会用到,所以提前配置好),注意@MapperScan(“com.komorebi.mapper”)注解。
配置类一定要加@Configuration。
@Configuration
@MapperScan("com.komorebi.mapper")
public class MybatisPlusConfig {
// 分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
跨域问题解决
创建WebMVCConfig配置类,解决不同端口之间的跨域问题
配置类一定要加@Configuration。
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("/**")
.allowCredentials(true)
.allowedOrigins("http://localhost:8080")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
二、首页配置
首页分页显示文章信息
@RestController//JSON数据交互
@RequestMapping("articles")
public class ArticleController {
@Autowired
ArticleService articleService;
//分页显示文章列表
@PostMapping
public Result listArticle(@RequestBody PageParams pageParams){
return articleService.listArticle(pageParams);
}
}
vo类
Vo包中的类才是前端实际拿到的数据。
文章显示控制类返回的是一个Result对象,参数是PageParams对象,这两个类都放在vo包中,vo中的类都是前端显示数据的类,一般前端中只显示数据库表中部分数据。
Result类,定义了两个静态方法,分别表示请求成功、请求失败。
package com.komorebi.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
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);
}
}
前端传给后端接口的json数据,我们都封装为param类,方便操作。
PageParams 类定义了分页查询的page和pageSize,分别对应分页查询中的start和size。
package com.komorebi.vo;
import lombok.Data;
@Data
public class PageParams {
private int page = 1;
private int pageSize = 1;
}
ArticleVo 类是前端显示文章信息的类,所以在查询文章列表时,就要做数据库中Article类向ArticleVo 类的转换。
package com.komorebi.vo;
import lombok.Data;
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<TagVo> tags;
//暂时不需要
// private CategoryVo category;
}
TagVo 类是前端显示标签信息的类,所以在查询文章列表时,就要做数据库中Tag类向TagVo 类的转换。
package com.komorebi.vo;
import lombok.Data;
@Data
public class TagVo {
private Long id;
private String tagName;
}
mapper接口
此处定义了三个mapper接口,分别为ArticleMapper、SysUserMapper、TagMapper。
package com.komorebi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.komorebi.pojo.Article;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ArticleMapper extends BaseMapper<Article> {
}
--------------------------------------------------------------
@Repository
public interface TagMapper extends BaseMapper<Tag> {
List<Tag> findTagsByArticleId(Long articleId);
}
-------------------------------------------------------------
@Repository
public interface SysUserMapper extends BaseMapper<SysUser> {
}
因为tag和article有一张对应的表,所以要查询article对应的tag时,需要设计到多表的查询,但是,mybatisplus不支持多表查询,所以需要自己写mapper.xml文件。
注意:mapper.xml文件所在目录要和mapper对应,本次工程都在com.komorebi.mapper下。
可以在application.properties中mybatis-plus开启驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true
这样SQL语句就不需要as别名。
TagMapper.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.komorebi.mapper.TagMapper">
<select id="findTagsByArticleId" parameterType="long" resultType="com.komorebi.pojo.Tag">
# 可以在application.properties中mybatis-plus开启驼峰命名
# mybatis-plus.configuration.map-underscore-to-camel-case=true
# 这样SQL语句就不需要as别名
select id,avatar,tag_name as tagName from ms_tag
where id in
(select tag_id from ms_article_tag where article_id=#{articleId})
</select>
</mapper>
service层部分
该阶段定义了三个service接口类。
package com.komorebi.service;
import com.komorebi.vo.PageParams;
import com.komorebi.vo.Result;
public interface ArticleService {
//分页查询文章列表
Result listArticle(PageParams pageParams);
}
--------------------------------------------------------
package com.komorebi.service;
import com.komorebi.pojo.SysUser;
public interface SysUserService {
SysUser findUserById(Long id);
}
--------------------------------------------------------
package com.komorebi.service;
import com.komorebi.vo.TagVo;
import java.util.List;
public interface TagService {
//通过文章id查询ui赢得标签,有一张表专门映射文章id和标签id
List<TagVo> findTagsByArticleId(Long articleId);
}
serviceImpl类
ArticleServiceImpl
该实现类目前实现了文章分页查询。
知识点:
1)Page类定义分页对象;
2)LambdaQueryWrapper定义查询wrapper;
3)selectPage()函数返回的是Page对象,通过getRecords获得Article对象列表。
4)copy和copyList函数实现Article到ArticleVo的转换
5)BeanUtils.copyProperties(article,articleVo),可以实现对象之间的复制,相同属性名复制,不同属性名为null。
package com.komorebi.service;