SpringBoot项目从零搭建
0、工具和环境配置
工具和环境配置清单如下,给出了软件版本、安装教程、入门教程的链接,可以给读者提供关键线索,个别细节读者自行Google解决即可
0.1、工具
作用 | 名称 | 版本 | 备注 |
---|---|---|---|
web服务器 | Tomcat | ||
版本管理 | Git | latest | |
代码开发工具 | IDEA | 2020.1 | |
数据库可视化工具 | Navicat | 15.0.2 | |
建模工具 | PDMan | 2.2.0 | Gitee下载、教程 |
Restful测试工具 | PostMan |
0.2、开发环境
名称 | 版本 | 注释 |
---|---|---|
JDK | 11 | 官方安装包 |
MySQL | 5.7.32 | |
Redis | 5.0.5 | 下载及安装 |
SpringBoot | 2.2.13.RELEASE | 官网 |
Maven | 3.3.3 | |
Knife4j | 2.0.7 | 官方教程 |
Mybatis | 2.1.4(latest) | mybatis-spring-boot-starter |
Druid | 1.2.4(latest) | druid-spring-boot-starter |
1、SpringBoot工程项目搭建
1.1、依赖配置
注意:依赖是逐步添加的,根据调试一个一个功能的加,这里给出的是全部的依赖
<?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.kkb</groupId>
<artifactId>qa-v01</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>11</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.13.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</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.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>
</project>
1.2、application.yml文件配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/qa?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
# Mybatis配置
mybatis:
type-aliases-package: com.kkb.entity
mapper-locations: classpath:/mappers/*.xml
# Redis配置
redis:
host: 192.168.37.141
port: 6379
1.3、生成启动器
常规操作,需要注意的是MapperScan这里导的是tk-mybatis的包
@SpringBootApplication
@MapperScan("com.kkb.mapper")
public class QaApplication {
public static void main(String[] args) {
SpringApplication.run(QaApplication.class, args);
}
}
1.4、实体类生成
关注以下2点:
- 属性和字段映射
- 使用Swagger的@ApiModelProperty注解可以标记属性是否是必须,方便调试
package com.kkb.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Table(name = "answer")
@Data
@ApiModel(value = "答案实体类")
public class Answer {
/**
* 主键Id,非空属性
*/
@Id
@Column(name = "Id")
@ApiModelProperty(required = true, name = "id", value = "主键id")
private String id;
/**
* 内容
*/
@Column(name = "Content")
private String content;
/**
* 支持数量
*/
@Column(name = "SupportCnt")
private Integer supportCnt;
/**
* 反对数量
*/
@Column(name = "OpposeCnt")
private Integer opposeCnt;
/**
* 回应问题的Id
*/
@Column(name = "AnswerTo")
private String answerTo;
/**
* 答案创建时间
*/
@Column(name = "time")
private Date time;
/**
* 用户Id
*/
@Column(name = "UserId")
private String userId;
/**
* 是否采纳,非空属性
*/
@Column(name = "accept")
@ApiModelProperty(required = true)
private Integer accept;
/**
*
* 非空属性
*/
@Column(name = "praise")
@ApiModelProperty(required = true)
private Integer praise;
}
1.5、mapper层
通用Mapper自带了常见的CRUD方法,只需要将自己接口类继承Mapper接口类即可使用。如
public interface AnswerMapper extends Mapper<Answer> {
}
对于复杂的CRUD操作,读者需要在接口类中定义方法,在xml中书写sql语句及结果映射。
1.6、Service层
service层里完成主要的业务处理,在这里加入了Redis的缓存,类型为String
package com.kkb.service.impl;
import com.kkb.common.http.HttpResult;
import com.kkb.common.utils.JsonUtils;
import com.kkb.entity.Answer;
import com.kkb.mapper.AnswerMapper;
import com.kkb.service.AnswerService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author: PengLuo
* @Create: 2021/1/22
*/
@Service
public class AnswerServiceImpl implements AnswerService {
@Autowired
private AnswerMapper answerMapper;
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public HttpResult findAllAnswers() {
// 查询缓存
String json = redisTemplate.opsForValue().get("answerList");
if (StringUtils.isNotBlank(json)) {
List<Answer> list = JsonUtils.jsonToList(json, Answer.class);
System.out.println("查询缓存成功");
return HttpResult.ok(list);
}
// 缓存里没有,则查询数据库,并把查询结果存入缓存
List<Answer> list = answerMapper.selectAll();
redisTemplate.opsForValue().set("answerList", JsonUtils.objectToJson(list));
return HttpResult.ok(list);
}
@Override
public HttpResult addAnswer(Answer answer) {
// id可设计为系统自动生成,参考雪花算法
int result = answerMapper.insert(answer);
if (result == 1) {
return HttpResult.ok("succeed add");
} else {
return HttpResult.error("add failure");
}
}
@Override
public HttpResult deleteById(String id) {
// 根据id查出answer,将accept字段值修改为no,表示逻辑删除,前端不予展示即可
Answer answer = answerMapper.selectByPrimaryKey(id);
if (answer != null) {
answer.setAccept(1);
int result = answerMapper.updateByPrimaryKeySelective(answer);
if (result == 1) {
return HttpResult.ok("delete succeed");
} else {
return HttpResult.error("delete failure");
}
} else {
return HttpResult.error("delete failure");
}
}
@Override
public HttpResult update(Answer answer) {
int result = answerMapper.updateByPrimaryKeySelective(answer);
if (result == 1) {
return HttpResult.ok("update succeed");
} else {
return HttpResult.error("update failure");
}
}
}
1.7、Controller层
Restful风格的API接口测试
1.8、单元测试
常规操作
1.9、PostMan测试
常规操作
1.10、Swagger配置及测试
Swagger的配置参考knife4j官网的配置,访问http://localhost:8080/doc.html可跳转到交互界面。需要指出的就是
接口文档、接口调试、导出为markdown或其它格式在这里都很方便的完成