直接上干货
先建一个springboot项目,这里使用的是IDEA的快速搭建springboot项目
直接点next
第一个是组名(随意)
第二个是项目名(随意)
java选择8版本的,不要问我为什么,因为现在市场上java8是主流,高版本的新特性太多了,人们还没完全用上
点next就行了
可以看到左侧有一些选项,可以选择需要使用的勾上,当然也可以不勾,勾上之后会在项目初始化的时候帮你把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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.qcby.hdz</groupId>
<artifactId>work2_3_sjw</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>work2_3_sjw</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
上面这是项目初始的pom文件
在pom文件加入springboot的核心启动依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
再数据库连接驱动的下面加入mybatisPlus的依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 整合mybatisPlus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
再整合log4j2日志框架(可要可不要)
因为spring里面自带了一个叫logback的日志框架,所以需要排除这个依赖,
因此修改springboot核心依赖如下:
<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>
再整合swgger接口文档测试,添加以下依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
以上为所需环境的所有依赖,有了这些,项目就可以运行了,虽然这些框架都有自己的默认配置,但是我们一般都会修改配置文件,比如配置数据库连接,mybatisplus的配置,日志打印,swgger配置等等
默认情况下会自动生成一个application.properties的文件,实际开发中更喜欢用application.ymi文件,两种文件的功能是一致的,因此我们把properties后缀名的文件修改为yml
首先配置数据库连接,账号密码填自己的
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo0624?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT
username: root
password: 123
driver-class-name: com.mysql.cj.jdbc.Driver
再配置mybatisPlus
# mybatis-plus配置
mybatis-plus:
typeAliasesPackage: com.qcby.hdz.work2_3_sjw.entity
mapperLocations: classpath:mapper/*.xml
configuration:
# log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
上面配置了日志输出,在开发时要用到控制台输出(StdOutImpl),所有选择了它
项目上线之后就要用上面的日志输出了(Log4j2),在日志文件中输出
除此之外,需要让日志在文件中输出,必须配置一个日志的xml文件(log4j2.xml)
文件内容如下:
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j2能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
<Properties>
<!-- 配置日志文件输出目录 -->
<Property name="LOG_HOME" value="F:\qcby\gitProject\0620\logs" />
</Properties>
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<Console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</Console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
<File name="log" fileName="${LOG_HOME}//test.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${LOG_HOME}/warn.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${LOG_HOME}/error.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效
!! DEBUG => 研发
!!INFO => 研发
!!ERROR => 生产环境
...
每10M 生成一个文件
每天或者间隔多长时间生成一个文件
-->
<loggers>
<root level="INFO">
<appender-ref ref="Console"/>
<!--暂时注释文件日志输出-->
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>
这个日志的配置文件内容要点如下:
① 输出日志的级别大小
② 日志输出的文件路径
③ 需要输出的日志级别
下图是控制需要输出日志级别:
备注:一般开发阶段都是info级别或debug级别居多,项目上线以后都是error级别,而且配置之后,日志会打印当前级别及以上级别的日志信息
MybatisPlus是自带分页插件的,如果我们需要用分页功能的话还需要单独建一个配置类来集成分页插件
java类如下:
@Configuration
public class MybatisPlusConfig {
// 最新版
@Bean // <bean id=""/>
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
好了,mybatisPlus和日志功能都配好了,现在来配置一下swgger生成接口文档(可要可不要,供测试用)
在application.yml文件中加入以下配置
swagger:
title: 图书管理系统项目RESTful API
description: 我很懒,什么都没写
version: 1.0
contactName: hdz
contactEmail:
contactUrl:
basePackageRest: com.qcby.hdz.work2_3_sjw.controller
termsOfServiceUrl:
这个是自定义配置,因为我们需要创建一个类来读取这个配置,所以是自定义的
现在我们单独建一个swgger的配置类:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Autowired
private SwaggerProperties swaggerProperties;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("REST接口")
.apiInfo(apiInfo())
.select()
// 配置自动扫描那些包下类型生成接口文档
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackageRest()))
.build();
}
//构建 api文档的详细信息函数,注意这里的注解引用的是哪个
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//页面标题
.title(swaggerProperties.getTitle())
//创建人
.contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(),swaggerProperties.getContactEmail()))
//版本号
.version(swaggerProperties.getVersion())
//描述
.description(swaggerProperties.getDescription())
.build();
}
}
内容都是固定的,我们没有必要去硬记
以上就是把环境整合好了,现在我们可以测试功能了
我们先把基本的包结构建立出来(其实mybatisplus可以自动生成,但是这里没有用这个功能)
我们先建一个Student类:
@Data
public class Student {
private Long id;
private String studentNum;
private Integer gender;
private String studentName;
private Integer age;
private Long classInfoId;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private ClassInfo classInfo;
private List<BorrowRecord> borrowRecordList;
}
@Data的作用就是给我们的类自动提供getter和setter方法,还有toString方法等等,省去了大量的代码(是不是看起来超简洁)
再建一个StudentMapper:
public interface StudentMapper extends BaseMapper<Student> {
}
为了使用mybatisPlus提供的通用方法,我们必须继承BaseMapper
再建一个StudentService:
public interface StudentService extends IService<Student> {
}
同样,也要继承IService,因为我们要使用mybatisPlus的通用方法
再建一个实现类StudentServiceImpl:
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
@Autowired
private StudentMapper studentMapper;
}
我们注入了StudentMapper并且加上了@Service注解,表示这个交给Spring容器管理了,在Controller层就能直接注入了
再建一个StudentController类
@RestController
@RequestMapping("/student")
@Api(tags = {"学生接口"})
public class StudentController {
@Autowired
private StudentService studentService;
}
Controller已经注入了StudentService并且使用了@Api注解生成接口文档
现在测试一下mybatisplus的通用增删改查方法,代码如下
@RestController
@RequestMapping("/student")
@Api(tags = {"学生接口"})
public class StudentController {
@Autowired
private StudentService studentService;
/**
* 获取所有学生信息
*
* @return {@link List<Student>}
*/
@ApiOperation(value = "获取所有学生信息")
@GetMapping("listAll")
public List<Student> listAll(){
return studentService.list();
}
/**
* 插入学生信息
*
* @param student 学生
* @return {@link Result}
*/
@ApiOperation(value = "添加学生信息")
@PostMapping("insert")
public Result insert(Student student){
boolean flag = studentService.save(student);
return Result.ok();
}
/**
* 根据id删除学生信息
*
* @param id id
* @return {@link Result}
*/
@ApiOperation(value = "根据id删除学生信息")
@DeleteMapping("deleteById")
public Result deleteById(Long id){
boolean flag = studentService.removeById(id);
return Result.ok();
}
/**
* 批量删除学生信息
*
* @param ids id
* @return {@link Result}
*/
@ApiOperation(value = "根据id批量删除学生信息")
@DeleteMapping("deleteByIds")
public Result deleteById(@RequestParam List<Long> ids){
boolean flag = studentService.removeByIds(ids);
return Result.ok();
}
/**
* 修改学生信息
*
* @param student 学生
* @return {@link Result}
*/
@ApiOperation(value = "修改学生信息")
@PutMapping("updateById")
public Result updateById(Student student){
studentService.updateById(student);
return Result.ok();
}
}
Result类是一个统一的结果返回类:
@Data
public class Result {
private int code;
private String msg;
private Map<String,Object> data = new HashMap<>();
public static Result ok(){
Result result = new Result();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMsg(ResultCode.SUCCESS.getMsg());
return result;
}
public static Result error(){
Result result = new Result();
result.setCode(ResultCode.ERROR.getCode());
result.setMsg(ResultCode.ERROR.getMsg());
return result;
}
public Result data(String key,Object value){
this.data.put(key,value);
return this;
}
}
public enum ResultCode {
SUCCESS(200,"成功"),
ERROR(500,"失败");
private int code;
private String msg;
ResultCode(int code,String msg){
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg(){
return msg;
}
}
启动项目进行测试,由于我们集成了Swgger,我们可以直接测试
这是swgger的如果,这个是固定的地址
下面是swgger界面:
我们要测试学生接口:
测试的话这里就不再赘述了(这不是有手就行?)