IDEA基于SpringBoot搭建Spring+SpringMVC+MyBatis Plus Maven项目,结合Swagger 2开发REST API
IDEA基于SpringBoot搭建Spring+SpringMVC+MyBatis Maven项目,结合Swagger 2开发REST API看了好几篇博客没有找到想要的资料,把自己的经验总结写下来,希望对大家有帮助。1. 创建数据库建表CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` va...
使用SpringBoot+Mybatis-Plus+Maven+Swagger能够快速开发出简单的Restful API把自己的经验总结写下来,希望对大家有帮助。
目录
1. 创建数据库建表
数据库名为demo,字符集选择utf-8,建表如下:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`sex` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
随便插入了几条数据,如下:
2.项目初始化
选择Spring Initializr初始化项目,如果熟练可直接选择maven构建
包名什么的根据实际情况填写
开发工具选择SpringBoot DevTools和Lombok,SpringBoot DevTools包含了SpringBoot的打包部署插件,而Lombok是用来简化代码的
由于是要开发API,选择Spring Web
选择数据库Mysql和Mybatis
娶个名字,Finish
项目初始化之后会生成pom.xml文件,前面的选择就是为了这个文件的内容。如果熟悉可以不选,直接copy依赖过来就好。
选择Enable-Auto Import,自动导包。需要一些时间。。。
如果特别慢的话那有可能是maven镜像源的问题,推荐使用阿里镜像,具体配置方案参考https://blog.csdn.net/NathanniuBee/article/details/80402675
3 项目构建
3.1 修改pom依赖
由于我想偷个懒,直接叫上mybatis的兄弟mybatis plus来帮忙,它封装好了基本的CRUD(也就是对基本表的增删改查)还可以配置模板代码生成,很强。使用以下依赖替换掉原来的mybatis依赖即可。本是同根生,相煎何太急啊。没错是替换。。。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!--mybaits-plus生成代码的依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
添加加swagger 2依赖,在<dependencies></dependencies>中找个坑位放下↓
<dependency><!--添加Swagger依赖 -->
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency><!--添加Swagger-UI依赖 -->
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--引入swagger-bootstrap-ui替换原生Swagger-UI-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
3.2 代码生成
配置代码生成,这个套代码有很多,mybatis-plus官网也有提供,有些地方还是需要修改一下的。。
package com.rest.example.demo.utils;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* 代码生成
*/
public class CodeGeneration {
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (ipt!=null) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
/**
* @param args
* @Title: main
* @Description: 生成
*/
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
final String projectPath = System.getProperty("user.dir") ;
String filePath = projectPath + "/src/main/java";
System.out.println("生成文件 的路径为:" + filePath);
gc.setOutputDir(filePath);
// gc.setOutputDir("E://code");
// gc.setFileOverride(true);
// gc.setActiveRecord(false);// 不需要ActiveRecord特性的请改为false
// gc.setEnableCache(false);// XML 二级缓存
// gc.setBaseResultMap(true);// XML ResultMap
// gc.setBaseColumnList(false);// XML columList
gc.setOpen(false);
gc.setAuthor("Champ.Ping");// 作者
// 自定义文件命名,注意 %s 会自动填充表实体属性!
// gc.setControllerName("%sAction");
// gc.setServiceName("%sService");
// gc.setServiceImplName("%sServiceImpl");
// gc.setMapperName("%sMapper");
// gc.setXmlName("%sMapper");
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL);
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false");
mpg.setDataSource(dsc);
// 包配置
final PackageConfig pc = new PackageConfig();
// pc.setModuleName("");
pc.setParent("com.rest.example.demo");
//以下生成的类类型的map的KEY值,可以去常量类中ConstVal获得,为了省事,直接写了字符串
Map m = new HashMap();
m.put("entity_path", gc.getOutputDir() + File.separator + (pc.getParent().replaceAll("\\.", "\\" + File.separator)) + "/entity");
m.put("mapper_path", gc.getOutputDir() + File.separator + (pc.getParent().replaceAll("\\.", "\\" + File.separator)) + "/mapper");
m.put("service_path",gc.getOutputDir() + File.separator + (pc.getParent().replaceAll("\\.", "\\" + File.separator)) +"/service");
m.put("service_impl_path",gc.getOutputDir() + File.separator + (pc.getParent().replaceAll("\\.", "\\" + File.separator)) + "/service/impl");
m.put(ConstVal.CONTROLLER_PATH,gc.getOutputDir() + File.separator + (pc.getParent().replaceAll("\\.", "\\" + File.separator)) + "/controller");
//m.put(ConstVal.XML_PATH,gc.getOutputDir() + File.separator + (pc.getParent().replaceAll("\\.", "\\" + File.separator)) + "/xml");
pc.setPathInfo(m);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
cfg.setFileOutConfigList(null);
mpg.setCfg(cfg);
mpg.setPackageInfo(pc);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
// templateConfig.setXml(TEMPLATE_XML);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setTablePrefix("");
// strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
strategy.setEntityLombokModel(true);
strategy.setEntitySerialVersionUID(true);
strategy.setRestControllerStyle(true);
// 写于父类中的公共字段
strategy.setSuperEntityColumns("id");
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
// strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// 执行生成
mpg.execute();
System.out.println("OK!!!");
}
}
运行这个类,按照控制台提示输入表名,回车,见证奇迹--->
代码生成完成,看看成果,完美。。
4 项目配置
4.1 修改配置文件
先修改配置文件,找到application.properties重命名application.yml,个人觉得yml的语法更加人性化一些。注意,yml文件考的是缩进,不要手抖。
其重命名后的application.yml内容如下:(看不明白找找yml资料,3分钟上手)
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: 123456
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:/mybatis/*Mapper.xml
typeAliasesPackage: com.rest.example.demo.entity
global-config:
db-config:
id-type: auto
4.2 添加Mapper注解
配置mapper,在SpringBoot主类上添加注解
@MapperScan("com.rest.example.demo.mapper")
4.3 配置Swagger 2
之前依赖已经加上,只需添加一个配置类即可,新建包config,添加类如下,注意有些地方要改
附源码如下:
package com.rest.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration //标记配置类
@EnableSwagger2 //开启在线接口文档
public class Swagger2Config implements WebMvcConfigurer {
/**
* 添加摘要信息(Docket)
*/
@Bean
public Docket controllerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("REST API Demo_接口文档")
.description("这是一个demo的后台服务")
.contact(new Contact("Champ_Ping","http://www.******.com/","123456@qq.com"))
.version("版本号:1.0.0")
.build())
.select()
.apis(RequestHandlerSelectors.basePackage("com.rest.example.demo.controller"))
.paths(PathSelectors.any())
.build();
}
}
5 接口实现
由于是单表,我们就用mybatis plus提供的CRUD就已经满足了。代码生成已经到Controller层了,因此,只需在Controller层开发即可。如果有些地方觉得生疏,要去看看Spring基础。
5.1 封装消息响应类
首先我们需要一个消息响应类 Response 定义响应格式,我把它放到utils包下,源码如下(我这个封装不是太完美,可以自己去网上找个更好的):
package com.rest.example.demo.utils;
import java.util.HashMap;
import java.util.Map;
public class Response extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public Response() {
put("code", 1);
put("message", "操作成功");
put("data", null);
}
public static Response error() {
return error(0,"操作失败");
}
public static Response error(String message) {
return error(0, message);
}
public static Response error(int code, String message) {
Response response = new Response();
response.put("code", code);
response.put("message", message);
response.put("data", null);
return response;
}
public static Response ok(String message) {
Response response = new Response();
response.put("message", message);
response.put("data", null);
return response;
}
public static Response ok(Object data) {
Response response = new Response();
response.put("data", data);
return response;
}
public static Response ok(String message,Object data) {
Response response = new Response();
response.put("message", message);
response.put("data", null);
return response;
}
public static Response ok(Map<String, Object> map) {
Response response = new Response();
response.putAll(map);
return response;
}
public static Response ok() {
return new Response();
}
@Override
public Response put(String key, Object value) {
super.put(key, value);
return this;
}
}
5.2 开发接口
有了响应类,开始实现接口,这个考的是Swagger 2注解以及Spring MVC的基础,具体代码如下:
package com.rest.example.demo.controller;
import com.rest.example.demo.entity.User;
import com.rest.example.demo.service.IUserService;
import com.rest.example.demo.utils.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* <p>
* 前端控制器
* </p>
*
* @author Champ.Ping
* @since 2020-05-05
*/
@Api(tags = {"用户接口"})
@RestController
@RequestMapping("")//系统模块名称,没有则不写,具体看接口是怎么设计的
public class UserController {
@Autowired
private IUserService userService;
@PostMapping("/user")
@ApiOperation("增加用户")
public Response save(@RequestBody User user){
try{
return Response.ok(userService.save(user));
}catch (Exception e){
return Response.error();
}
}
@DeleteMapping("/user/{id}")
@ApiOperation("根据Id删除用户")
public Response removeById(@PathVariable Integer id){
try{
return Response.ok(userService.removeById(id));
}catch (Exception e){
return Response.error();
}
}
@PutMapping("/user/{id}")
@ApiOperation("修改用户")
public Response update(@PathVariable Integer id,@RequestBody User user){
try{
user.setId(id);
return Response.ok(userService.updateById(user));
}catch (Exception e){
return Response.error();
}
}
@GetMapping("/users")
@ApiOperation("获取所有用户")
public Response listAll(){
try{
return Response.ok(userService.list());
}catch (Exception e){
return Response.error();
}
}
@GetMapping("/user/{id}")
@ApiOperation("根据Id查询用户")
public Response getById(@PathVariable Integer id){
try{
return Response.ok(userService.getById(id));
}catch (Exception e){
return Response.error();
}
}
}
5.3 接口请求类注解
还有个地方需要改一下,那就是entity,需要加上swagger的一些注解,方面搞前端的队友看得明白。
代码如下:
package com.rest.example.demo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author Champ.Ping
* @since 2020-05-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
@ApiModel("用户实体")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id",hidden = true)
private Integer id;
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty(value = "性别",notes = "0:未知 1:男 2:女")
private Integer sex;
}
6 接口测试
6.1 运行项目
设么都别说了,先把项目跑起来再说,选中SpringBoot主类上右键,run它。启动后界面如下
跑起来之后在浏览器输入http://127.0.0.1:8081/doc.html或http://127.0.0.1:8081/swagger-ui.html可以访问到利用Swagger生成的在线接口文档,我们可以用它来做接口测试,当然也可以用Postman,界面如下:
bootstrap-UI
swagger原生UI
两套UI都是Swagger提供的,推荐使用Bootstrap UI,但是我也保留了原生的UI,毕竟萝卜白菜各有所爱。
之前给实体添加的注解在下面这个图可以体现出来:
6.2 列表查询测试
废话不所说,直接测试,我用Bootstrap UI,打开一个接口页面,点击调试:
这个请求不需要参数,直接点击发送,我们可以看到返回的所有用户:
6.3 添加测试
再试试添加,点开增加页面,我们前后端交互的是Json,由于之前实体类的注解,会有默认的Json提示,修改后点击发送:
很神奇,我们的操作成功了,下面是返回的数据:
我们去数据看看,数据也有了:
6.4 删除测试
输入Id,发送请求,OKK
看数据库,刷新一下这条数据蒸发了:
6.5 修改测试
输入id,和修改的内容,发送--->
服务器返回OK
数据库刷新一下,也OK
6.6 查询测试
输入Id,发送,又OKK
本文结束了,有什么问题可以留言,虽然我不一定及时看得到,但我总是会看到的。
更多推荐
所有评论(0)