使用SpringBoot+Mybatis-Plus+Maven+Swagger能够快速开发出简单的Restful API把自己的经验总结写下来,希望对大家有帮助。

目录

1. 创建数据库建表

2.项目初始化

3 项目构建

3.1 修改pom依赖

3.2 代码生成

4 项目配置

4.1 修改配置文件

4.2 添加Mapper注解

4.3 配置Swagger 2

5 接口实现

5.1 封装消息响应类

5.2 开发接口

5.3 接口请求类注解

6 接口测试

6.1 运行项目

6.2 列表查询测试

6.3 添加测试

6.4 删除测试

6.5 修改测试

6.6 查询测试

 

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.htmlhttp://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

本文结束了,有什么问题可以留言,虽然我不一定及时看得到,但我总是会看到的。

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐