初学者必看,SpringBoot+MybatisPlus+Swagger快速开发套路和总结(一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 初学者必看,SpringBoot+MybatisPlus+Swagger快速开发套路和总结(一)

一、模块开发


Mybatis-Plus快速入门_小蜗牛耶的博客-CSDN博客_mybatis-plus

回顾可看我写的这篇文章

下文用boot代替springboot

mp代替mybatisplus

按照本文目录结构即可快速开发一套完整的CRUD接口,包括后面的Swagger测试


快速开发套路


这一套东西就是写接口对吧,所以==写接口也就是写业务类,写业务类有个小口诀==

  1. 建表写sql
  2. 定义实体类
  3. dao与mapper
  4. service和impl
  5. controller

那么我们用==boot写微服务模块==也有个小套路

  1. 建module
  2. 改pom
  3. 写yml
  4. 主启动
  5. 业务类

业务类对标我们上面的顺序


建module


建立新项目的时候可以用spring initializr初始化boot项目,也可以用maven的方式创建。这里我采用maven的方式来创建

image.png


改pom


pom出现的问题,跟网络环境有很大关系。

pom如果不断出错,可以更换网络或者删掉本地仓库中的包,重下


<?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.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.caq</groupId>
    <artifactId>mybatisplusdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatisplusdemo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <scope>provided</scope>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>

yml


这里我采用mysql8.0以上的驱动,配置url到时候?后面的值必须要加

驱动的名称和mysql5的也不一样记得区分


#端口号
server:
  port: 8003
#服务名
spring:
  application:
    name: service-edu
  #返回json的全局时间格式
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatisplus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
  profiles:
    active: dev
# mybatis日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

主启动


package com.caq.mybatisplusdemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MybatisplusdemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisplusdemoApplication.class, args);
    }
}


二、业务类开发


业务类(手动)


下面就开始写业务类了,业务类也遵守我们的步骤来写


建表写sql


CREATE TABLE user01
(
    id int(20) NOT NULL COMMENT '主键ID' ,
    name01 VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age01 INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email01 VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);
DELETE FROM user01;
INSERT INTO user01 (id, name01, age01, email01) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');


实体类、dao、service


这里我们采用mp的插件,一键完成创建

==安装插件==

image.png

==idea中连接数据库==

image.png

==右键你要一键生成实体类,dao,service的表格generator即可==

image.png

==生成说明==

image.png

image.png

image.png

==service接口说明==

image.png

==那么我们是不是要实现这么多方法呢?==

当然不用,mp给我们定义好了一个IService的实现类,我们只需要实现类继承它并实现接口即可

image.png


controller


调用service,service调用mapper(dao)

开发controller,service,dao的过程就叫开发接口

为了前后端更好的沟通,我们可以定义一个统一的返回类


统一返回类


状态码定义

package com.caq.commonutils;
public interface ResultCode {
    //状态码:成功
    public static Integer SUCCESS = 20000;
    //状态码:失败
    public static Integer ERROR = 20001;
}

统一返回类型R

package com.caq.commonutils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
 * 结果类
 */
@Data
public class R<T> {
    @ApiModelProperty(value = "是否成功")
    private Boolean success;
    @ApiModelProperty(value = "返回码")
    private Integer code;
    @ApiModelProperty(value = "返回消息")
    private String message;
    @ApiModelProperty(value = "返回数据")
    private Map<String, Object> data = new HashMap<>();
    //私有的构造器
    private R() {}
    //成功的静态方法
    public static R ok() {
        R r = new R();
        r.setSuccess(true);
        r.setCode(ResultCode.SUCCESS);
        r.setMessage("您的操作成功啦(*^▽^*)");
        return r;
    }
    //失败的静态方法
    public static R error() {
        R r = new R();
        r.setSuccess(false);
        r.setCode(ResultCode.ERROR);
        r.setMessage("您的操作失败啦(⊙︿⊙)");
        return r;
    }
    //the follow methods all return this,链式编程
    public R success(Boolean success){
        this.setSuccess(success);
        return this;
    }
    public R code(Integer code){
        this.setCode(code);
        return this;
    }
    public R message(String message){
        this.setMessage(message);
        return this;
    }
    public R data(String key, Object value){
        this.data.put(key, value);
        return this;
    }
    public R data(Map<String, Object> map){
        this.setData(map);
        return this;
    }
}


业务类(自动)


好,我们记住了这些固定的步骤之后其实还有个更简单的方式哦!

那就是mp里面的代码生成器!

下面直接放代码,因为它是固定的,我们只需要会更改即可


public class CodeGenerator {
    @Test
    public void genCode() {
        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("Pyy");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setServiceName("%sService"); //去掉Service接口的首字母I
        gc.setIdType(IdType.AUTO); //主键策略
        gc.setSwagger2(true);//开启Swagger2模式
        mpg.setGlobalConfig(gc);
        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/srb_core?serverTimezone=GMT%2B8&characterEncoding=utf-8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);
        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.caq");
        pc.setEntity("entity"); //此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
        mpg.setPackageInfo(pc);
        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok
        strategy.setLogicDeleteFieldName("is_deleted");//逻辑删除字段名
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);//去掉布尔值的is_前缀(确保tinyint(1))
        strategy.setRestControllerStyle(true); //restful api风格控制器
        mpg.setStrategy(strategy);
        // 6、执行
        mpg.execute();
    }
}

image.png


MP插件


业务类搞好后,为了让接口的功能更完善,我们最后加上mp自带的插件

baomidou.gitee.io/mybatis-plu…

mp的2.x文档更详细一点

下面分别介绍主要的插件和一些常见知识点


主键生成策略


下面是我对实体类字段进行的设置,

这样设置的话我的主键在每次创建新用户的时候都会自动填充为分布式全局唯一ID 字符串类型


private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "讲师ID")
/**
 * 分布式应用时,我们需要生成分布式ID,可以选择使用@TableId(type=IdType.ID_WORKER),数据库中的主键为:
 * IdType包括以下几类:
 * AUTO : 数据库主键自增
 * INPUT: 用户自行输入
 * ID_WORKER: 分布式全局唯一ID, 长整型
 * UUID: 32位UUID字符串
 * NONE: 无状态
 * ID_WORKER_STR: 分布式全局唯一ID 字符串类型
 */
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;

image.png


自动填充详解


自动填充一般应用在数据库创建时间或修改时间字段

[自动填充功能官网](自动填充功能 | MyBatis-Plus (baomidou.com))


配置类


package com.caq.servicebase.handle;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入的时候填充创建和修改字段
    @Override
    public void insertFill(MetaObject metaObject) {
        //属性名称,不是字段名称
        this.setFieldValByName("gmtCreate",new Date(),metaObject);
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }
//修改的时候填充修改字段
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }
}


定义字段


@ApiModelProperty(value = "创建时间")
@TableField(fill= FieldFill.INSERT)
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
@TableField(fill=FieldFill.INSERT_UPDATE)
private Date gmtModified;


测试自动填充


image.png


乐观锁


锁是针对数据冲突的解决方案

==悲观锁==

正如其名,它指的是对数据被外界修改持保守(悲观),因此在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制

==乐观锁==

相对悲观锁而言,乐观锁假设认为数据一般情况下不会有冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现了冲突,则让返回用户错误的信息,让用户决定如何去做。乐观锁的实现方式一般是记录数据版本

乐观锁的实现方式

  • 取出记录,获取当前Version
  • 更新时,带上这个version
  • 执行更新时,set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

image.png

乐观锁配置需要两步


配置插件


//乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    return new OptimisticLockerInterceptor();
}


在实体类的字段上加上@Version注解


@Version
private Integer version;


逻辑删除


只对自动注入的 sql 起效:

  • 插入: 不作限制
  • 查找: 追加 where 条件过滤掉已删除数据,且使用 wrapper.entity 生成的 where 条件会忽略该字段
  • 更新: 追加 where 条件防止更新到已删除数据,且使用 wrapper.entity 生成的 where 条件会忽略该字段
  • 删除: 转变为 更新

例如:

  • 删除: update user set deleted=1 where id = 1 and deleted=0
  • 查找: select id,name,deleted from user where deleted=0

字段类型支持说明:

  • 支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
  • 如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()

附录:

  • 逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
  • 如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。


配置


@Bean
public ISqlInjector sqlInjector() {
    return new LogicSqlInjector();
}


实体类字段上加上@TableLogic注解


@TableLogic
private Integer deleted;


分页


  • 自定义查询语句分页(自己写sql/mapper)
  • spring 注入 mybatis 配置分页插件


配置类


//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}


性能分析


性能分析拦截器,用于输出每条 SQL 语句及其执行时间

注意!该插件只用于开发环境,不建议生产环境使用。。。


配置类



         


通用CRUD


介绍完了mp的组件,要想使用只需要把它们写进一个配置类中让boot扫描即可


配置类


注入mp插件,完善接口功能

image.png


CRUD接口


package com.caq.mybatisplusdemo.controller;
@Api("crud测试")
@RestController
@RequestMapping("/testMP/user")
public class crudDemo {
    @Autowired
    UserService userService;
    @ApiOperation("增加用户")
    @PostMapping("save")
    public R saveUser(@RequestBody User user){
        boolean save = userService.save(user);
        if (save){
            return R.ok();
        }else {
            return R.error();
        }
    }
    @ApiOperation("查看所有用户")
    @GetMapping("list")
    public R listUser(){
        List<User> list = userService.list(null);
        return R.ok().data("items",list);
    }
    @ApiOperation("查看某个用户")
    @GetMapping("getByIdUser")
    public R getByIdUser(@PathVariable String id){
        User user = userService.getById(id);
        return R.ok().data("user",user);
    }
    @ApiOperation("按ID删除user")
    @DeleteMapping("delete")
    public R removeUser(@ApiParam(name = "id",value = "讲师ID",required = true)@PathVariable String id){
        boolean delete = userService.removeById(id);
        if (delete){
            return R.ok();
        }else {
            return R.error();
        }
    }
    @ApiOperation("按ID更改user")
    @PostMapping
    public R updateUser(@RequestBody User user){
        boolean update = userService.updateById(user);
        if (update){
            return R.ok();
        }else {
            return R.error();
        }
    }
}



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
49 0
|
2天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
31 13
|
10天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
18天前
|
Java 测试技术 API
详解Swagger:Spring Boot中的API文档生成与测试工具
详解Swagger:Spring Boot中的API文档生成与测试工具
32 4
|
21天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
36 2
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
67 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
2月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
159 1
|
2月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
36 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
2月前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
25 0
mybatis使用二:springboot 整合 mybatis,创建开发环境
|
1月前
|
JavaScript 前端开发 Java
SpringBoot_web开发-webjars&静态资源映射规则
https://www.91chuli.com/ 举例:jquery前端框架
20 0