资料下载
代码语言:javascript复制https://atgfwacnz-my.sharepoint.com/:f:/g/personal/gtfonedriver_365vip_eu_org/EiXUA7XZ5dBEpNS0o_m9og0BCib9dy2vQjztVuJbf4APMg?e=HNwCS2
第一章 开发环境准备和新版SpringBoot2.X项⽬创建
第1集 开发环境准备和新版SpringBoot2.X项⽬创建
简介:开发环境准备和说明
- 必备基础环境:JDK8或者JDK11版本 Maven3.5(采⽤默
认) IDEA旗舰版 Mysql5.7以上版本
- 不要⽤JDK11以上,⾮⼤规模的LTS版本且多数软件不⽀持
- 2021~2024年内,JDK11会是⼤规模流⾏
- 操作系统:Win10或者Mac苹果
- 创建新版SpringBoot2.X项⽬
- https://spring.io/projects/spring-boot
- 在线构建⼯具 https://start.spring.io/
- 注意: 有些包maven下载慢,等待下载如果失败
- 删除本地仓库spring相关的包,重新执⾏ mvn install
- 建议先使⽤默认的maven仓库,不⽤更换地址
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
</plugin>
</plugins>
</build>
第二章 写代码⻜的感觉-急速上⼿Lombok插件 原理
第1集 如果公司代码⾏数计算KPI-我稳拿第⼀
简介:介绍javaee框架开发和实体类POJO
- Javase开发
- 就是java基础技术栈,做java相关开发的基础,⽐如javaweb、javaee开发都是必备javase基础
- Javaweb
- 使⽤java开发⽹站相关技术,⽐如Servlet、JDBC、Tomcat、Session/Cookie等技术栈,javaweb⾥⾯很多技术,但有部分慢慢被弃⽤了,⽐如JSP等技术点企业很少⽤了前端基础:HTML CSS JS数据库基础:Mysql
- Javaee到微服务
- 全称Java Platform,Enterprise Edition,可以构建企业级的⾯向服务体系结构(service-orientedarchitecture,SOA)微服务、组件等的技术栈,更多的是框架层⾯开发构建⼤型应⽤
- 主流框架(当然现在还有少数公司⽤⽼旧项⽬):2015年:Struts Hibernate Spring SSH 2015~2018之间:SpringMVC Spring Mybatis
- SSM 2018年到现在:SpringBoot Spring Myabtis 新版SSM
- 微服务架构:MicroService : SpringCloud /AlibabaCloud
- ⽆服务架构:ServerLess
- 服务⽹格:Service Mesh
- 公司绩效要是能用代码行数计算,我稳拿第一
第2集 POJO类的提效利器Lombok插件IDEA安装
简介:讲解lombok的介绍和安装
- 什么lombok
- 官网:https://projectlombok.org/
- 一个优秀的Java代码库,简化了Java的编码,为Java代码的精简提供了一种方式
- 你是否发现每个JavaBean都会写getter,setter,equals,hashCode和toString的模板代码,特别的多于没技术
- lombok消除Java的冗长代码,尤其是对于简单的Java对象,只要加上注解就行
- 使用方式
- 项目添加依赖进行版本管理
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<!--https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.16-->
<!--scope=provided,说明它只在编译阶段生效,不需要打入包中, Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件-->
- 添加IDE工具对Lombok的支持
- 点击File-- Settings设置界面,安装Lombok插件,然后重启idea
- IDEA里需要在设置中启用annotation processors,记得重启IDEA!!!!
第3集 Lombok插件玩转注解Setter/Getter实战
简介:讲解lombok的常见注解Set/Get实战
- 基于项目的实体类测试
- User实体类
- 常见注解@Getter/@Setter
- 作用类上,生成所有成员变量的getter/setter方法
- 作用于成员变量上,生成该成员变量的getter/setter方法
- 编译查看字节码 mvn compile
- 进一步控制
- 方法控制访问级别 set和get注解加上 @Getter(AccessLevel.PROTECTED)
@Setter
@Getter
public class UserDO {
/**
* 不想生成 get方法
*/
@Getter(AccessLevel.NONE)
private int age;
/**
* 控制访问权限
*/
@Getter(AccessLevel.PROTECTED)
private int salary;
/**
* final 只会生成get
*/
private final String name="小红";
/**
* 下面两个静态成员变量不会生成set/get方法
*/
static Date createTime = new Date();
private static final String address = "广东省广州市";
}
第4集 Lombok插件玩转NonNull 构造函数注解ArgsConstructor实战
简介:讲解Lombok非空判断和构造函数注解
- @NonNull
- 作用于方法上或者属性,用于非空判断,如果为空则抛异常
public void login(@NotNull String pwd){
}
- @NoArgsConstructor
- 生成无参构造器
- @AllArgsConstructor
- 生成全参构造器
- @RequiredArgsConstructor
- 指定参数的构造函数,有以下的特征的字段
- final类型未被初始化的属性, 标记了@NonNull的属性
- 注意:@NoArgsConstructor不能加
- 指定参数的构造函数,有以下的特征的字段
第5集 知其然而知其所以然-Lombok插件原理-对比反射技术
简介:讲解JSR介绍和lombok原理讲解
- 光会用就行了?肯定是不行的啊,知其所以然才行的,实现这样神器的效果是咋做的?
- 熟悉Java自定义注解的同学已经猜到是: JSR 269插件化注解处理
JSR 269: Pluggable Annotation Processing API
实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件
地址:https://www.jcp.org/en/jsr/detail?id=269
- 科普
JSR是Java Specification Requests的缩写,意思是Java 规范提案。
是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。
任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
- Lombok解析流程如下
Javac 解析成AST抽象语法树后, Lombok根据自己编写的注解处理器,动态地修改 AST增加新的节点(即Lombok自定义注解所需要生成的代码),最终生成JVM可执行的字节码Class文件
可以看编译后的在target目录下的class文件
- 能实现上述效果的还有一个反射技术,那两个对比如何?
使用Annotation Processing自定义注解是在编译阶段进行修改
JDK的反射技术是在运行时动态修改
结论:反射更加灵活一些但是带来的性能损耗更加大
第三章 精通Lombok插件 Java面试核心巩固
第1集 Lombok插件玩转Debug必备利器toString()注解
简介:讲解lombok的toString()注解
- java bean对象为啥要重新toString方法?
- List或者其他集合调试不方便
- 控制台或者日志输出对象,默认打印的是内存地址
- @ToString
- 作用于类,覆盖默认的toString()方法
- 不包括某个字段
@ToString(exclude = {"age"})
- 只输出某个字段
@ToString(of = {"name"})
第2集 Java核心面试题-重温hashcode和equal方法
简介:重温Java核心知识hashcode和equal方法
- 为什么对象要重写hashcode和equal方法?
- HashCode⽅法
- 顶级类Object⾥⾯的⽅法,所有类都是继承Object的,返回值int类型
- 根据⼀定的hash规则(存储地址,字段,或者⻓度等),映射成⼀个数值,即散列值
- Equals⽅法
- 顶级类Object⾥⾯的⽅法,所有类都是继承Object的,返回值boolean类型
- 根据⾃定义的匹配规则,⽤于匹配两个对象是否⼀样, ⼀般逻辑是如下
- HashCode⽅法
//判断地址是否⼀样
//⾮空判断和class类型判断
//强转
//对象⾥⾯的字段⼀⼀匹配
解析
如果两个对象相等,那么它们的hashCode()值一定相同(这里的相等是指,通过equals()比较两个对象时返回true) 如果两个对象hashCode()相等,它们并不一定相等。在散列表中hashCode()相等,即两个键值对的哈希值相等。 然而哈希值相等,并不一定能得出键值对相等,就出现所谓的哈希冲突场景,还需判断equals⽅法判断对象是否相等
应用场景:当向集合中插⼊对象时,如何判别在集合中是否已经存在该对象,⽐如Set确保存储对象的 唯⼀,并判断是不是同个对象呢?
代码语言:javascript复制 依据hashCode和equals进⾏判断
所以Set存储的对象必须重写这两个⽅法 判断两个对象是否⼀样
⾸先判断插⼊obj的hashcode值是否存在,hashcode值不存在则直 接插⼊集合
值存在则还需判断equals⽅法判断对象是否相等
第3集 Lombok插件玩转对象匹配EqualsAndHashCode注解
简介:玩转lombok的EqualsAndHashCode注解
- @EqualsAndHashCode
- 作用于类,覆盖默认的equals和hashCode, 作用于全部属性
- 不包括某个属性
@EqualsAndHashCode(exclude = {"age"})
- 只输出某个属性
@EqualsAndHashCode(of = {"name"})
第4集 玩转Lombok插件多注解集合配置Data-项目常用
简介:玩转lombok的data注解
- Lombok前面讲了多个注解,一个个加也麻烦吧
- @Data, 定义一个干净的类,增加此注解,mvn compile查看字节码
- 作用于类上,是以下注解的集合
- @ToString
- @EqualsAndHashCode
- @Getter
- @Setter
- @RequiredArgsConstructor
第5集 设计模式之建造者模式和Lombok注解@Builder
简介:玩转设计模式之建造者模式和lombok的@Builder注解
- 帮你生成了set、get方法,还在苦苦的一个个赋值???
- 构造者模式:又称之为建造者模式
- 场景:当一个bean类重载了多个构造方法时,并且参数随机使用时,考虑使用构造者模式
- 谷歌的开源的protobuf协议生产的java bean赋值就是采用建造者模式
- @Builder注解
- 作用在类上
第6集 Log日志输出打印更方便Lombok注解@Log-@Slf4j
简介:玩转lombok的@Log日志注解
- @Log / @Slf4j
- 作用于类上,生成日志变量, 用于记录日志
- 如果不生效,记得检查下面的配置,另外重新更新下lombok插件,重启idea
- 开始按照创建的那边,记得开启 开启annotion processing
第7集 Lombok课程总结-优缺点适合场景
** Lombok课程总结-优缺点适合场景**
- Lombok插件是不是万能的???
- Lombok的使用要求一定要在IDE中安装对应的插件,如果项目组中有一个人使用了Lombok则都要用
- 代码可读性,可调试性低,比如想知道某个类中的某个属性的getter方法都被哪些类引用
- 影响升级,如果升级到某个新版本的JDK的时候,如果其中的特性在Lombok中不支持的话就会受到影响
- 注意常见的细节点
- 比如只使用了@Data,而不使用@EqualsAndHashCode(callSuper=true)的话,会默认是@EqualsAndHashCode(callSuper=false),这时候生成的equals()方法只会比较子类的属性,不会考虑从父类继承的属性,无论父类属性访问权限是否开放,只要知道是否需要使用父类的属性即可,也提供定制化配置,所以不用过多担心
- 优点:
- 使用注解即可帮忙自动生成代码
- 大大减少了代码量,使代码非常简洁
- 部分注解在业务项目中开发能大大提高效率
- 项目中应该用还是不用呢
- 不建议开发中间件的项目使用,中间件设计的要求是解耦少依赖
- 业务项目实体类可以用,且用的时候知道对应的常见的注解原理
- Lombok
@Setter/@Getter
@NonNull
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode
@Data
@Builder
@Log
@Slf4j
第四章 4⼩时玩转增强版ORM框架-MybatisPlus多场景应⽤
第1集 增强版ORM框架-Mybatis plus介绍和数据库准备
简介:增强版ORM框架 mybatis plus介绍
- 背景
- 如果写一个数据库表的crud接口,编写实体类-》编写Controller-》编写Service-》编写DAO-》-》编写XML文件
- 特别是管理后台,多数都是简单的CRUD,用普通的mybatis有的鸡肋
- 介绍
- 官网 https://baomidou.com/
- 是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生
- 是怎么增强的呢?已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,类似JPA但优于JPA
- 更多特性
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 数据库准备
- 资料里面有数据库,多个表 导入本地自己创建好的数据库
- 新建 class_shop 库
第2集 新版SpringBoot2.X整合MybatisPlus Lombok插件
简介:使用新版SpringBoot2.x整合MybatisPlus Lombok
- 新版SpringBoot整合
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis plus和springboot整合-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
- 增加数据库配置
server.port=8081
#==============================数据库相关配置========================================
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/class_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username =root
spring.datasource.password =123456
- 建立好包,配置springboot扫描路径
第3集 SpringBoot Mybatis plus案例商品轮播图整合实战
简介:SpringBoot整合Mybatis plus项目实战
- 基础准备
- 统一接口返回协议-JsonData
@Data
@AllArgsConstructor //会生成一个包含所有变量
@NoArgsConstructor //生成一个无参数的构造方法
public class JsonData {
/**
* 状态码 0 表示成功,1表示处理中,-1表示失败
*/
private Integer code;
/**
* 数据
*/
private Object data;
/**
* 描述
*/
private String msg;
/**
* 成功,传入数据
* @return
*/
public static JsonData buildSuccess() {
return new JsonData(0, null, null);
}
/**
* 成功,传入数据
* @param data
* @return
*/
public static JsonData buildSuccess(Object data) {
return new JsonData(0, data, null);
}
/**
* 失败,传入描述信息
* @param msg
* @return
*/
public static JsonData buildError(String msg) {
return new JsonData(-1, null, msg);
}
/**
* 失败,传入描述信息,状态码
* @param msg
* @param code
* @return
*/
public static JsonData buildError(String msg, Integer code) {
return new JsonData(code, null, msg);
}
}
- BannerDO类编写
@Data
@TableName("banner")//表名映射
public class BannerDO {
private Integer id;
private String img;
private String url;
private Integer weight;
}
- 开发controller-
@RestController
@RequestMapping("api/v1/banner")
public class BannerController {
@Autowired
private BannerService bannerService;
@RequestMapping("list")
public JsonData list() {
List<BannerDO> list = bannerService.list();
return JsonData.buildSuccess(list);
}
}
- service
public interface BannerService {
List<BannerDO> list();
}
@Service
public class BannerServiceImpl implements BannerService {
@Autowired
private BannerMapper bannerMapper;
@Override
public List<BannerDO> list() {
return bannerMapper.selectList(new QueryWrapper<>());
}
}
- mapper
public interface BannerMapper extends BaseMapper<BannerDO> {
}
第4集 集成Spring Boot Test单元测试和控制台sql日志打印
简介:项目集成Spring Boot Test单元测试 控制台数据sql
- 需求分析->设计->开发->测试->上线
- 单元测试: 完成最小的软件设计单元的验证工作,目标是确保模块被正确的编码
- Spring Boot Test 是在Spring Test之上的再次封装, 使用@SpringBootTest后,Spring将加载所有被管理的bean,等同于启动了整个服务
- 项目添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
- 项目新建测试
@SpringBootTest(classes = TestApplication.class)
@Slf4j
class BannerTest {
@Autowired
private BannerService bannerService;
@Test
public void testBannerList(){
List<BannerDO> list = bannerService.list();
log.info("轮播图列表:{}",list);
}
}
- Mybatis plus配置控制台打印日志
#配置mybatis plus打印sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
第5集 MybatisPlus核心类BaseMapper介绍
简介:介绍MybaitsPlus核心类BaseMapper
- 核心类介绍: Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
- 方法很多:记住常用的几个就行
/**
* Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
* <p>这个 Mapper 支持 id 泛型</p>
*
* @author hubin
* @since 2016-01-23
*/
public interface BaseMapper<T> extends Mapper<T> {
/**
* 插入一条记录
*
* @param entity 实体对象
*/
int insert(T entity);
/**
* 根据 ID 删除
*
* @param id 主键ID
*/
int deleteById(Serializable id);
/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,删除记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 删除(根据ID 批量删除)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 根据 ID 修改
*
* @param entity 实体对象
*/
int updateById(@Param(Constants.ENTITY) T entity);
/**
* 根据 whereEntity 条件,更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
/**
* 根据 ID 查询
*
* @param id 主键ID
*/
T selectById(Serializable id);
/**
* 查询(根据ID 批量查询)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 查询(根据 columnMap 条件)
*
* @param columnMap 表字段 map 对象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,查询一条记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* <p>注意: 只返回第一个字段的值</p>
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}
QueryWrapper介绍
- 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());
第6集 MybatisPlus多案例查询API实战
简介:介绍MybaitsPlus多案例查询API实战
- 多案例API查询
@SpringBootTest(classes = TestApplication.class)
@Slf4j
class BannerTest {
@Autowired
private BannerService bannerService;
@Autowired
private BannerMapper bannerMapper;
/**
* id查找
*/
@Test
public void testSelectById(){
BannerDO bannerDO = bannerMapper.selectById(1);
log.info("bannerDO: {}",bannerDO);
}
/**
* 批量查找
*/
@Test
public void testSelectBatchIds(){
List<BannerDO> list = bannerMapper.selectBatchIds( Arrays.asList(1,2));
log.info("bannerDO: {}",list);
}
/**
* 选择1条
*/
@Test
public void testSelectOne(){
BannerDO bannerDO = bannerMapper.selectOne(new QueryWrapper<BannerDO>().eq("id",1));
log.info("bannerDO: {}",bannerDO);
}
/**
* 统计行数
*/
@Test
public void testSelectCount(){
int size = bannerMapper.selectCount(null);
log.info("bannerDO: {}",size);
}
/***
* 查找全部数据
*/
@Test
public void testBannerList(){
List<BannerDO> list = bannerService.list();
log.info("轮播图列表:{}",list);
}
}
第五章 玩转MybatisPlus常⻅增删改查和分⻚
第1集 初识 Mybatis plus常用注解
简介:讲解 Mybatis plus 常用注解
- @TableName 用于定义表名
- @TableId 用于定义表的主键
- 属性
- value 用于定义主键字段名
- type 用于定义主键类型(主键策略 IdType)
- 主键策略
- IdType.AUTO 主键自增,系统分配,不需要手动输入
- IdType.NONE 未设置主键
- IdType.INPUT 需要自己输入 主键值
- IdType.ASSIGN_ID 系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)
- IdType.ASSIGN_UUID 系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)
- 属性
- @TableField 用于定义表的非主键字段
- 属性
value 用于定义非主键字段名,用于别名匹配,假如java对象属性和数据库属性不一样
exist 用于指明是否为数据表的字段, true 表示是,false 为不是,假如某个java属性在数据库没对应的字段则要标记为faslse
fill 用于指定字段填充策略(FieldFill,用的不多)
字段填充策略:一般用于填充 创建时间、修改时间等字段
FieldFill.DEFAULT 默认不填充
FieldFill.INSERT 插入时填充
FieldFill.UPDATE 更新时填充
FieldFill.INSERT_UPDATE 插入、更新时填充。
第2集 案例实战 Mybatis Plus 删除测试用例编写
简介: 案例实战 Mybatis Plus 新增测试用例编写
- 删除
- 根据id删除
- 条件删除
第3集 案例实战 MybatisPlus 多种update更新操作
简介: 案例实战 MybatisPlus 多种update更新操作
- queryWrapper更新操作
- updateWrapper更新操作
第4集 MybatisPlus查询封装类QueryWrapper比较API讲解
简介:介绍MybaitsPlus核心查询条件类QueryWrapper的比较API讲解
- QueryWrapper介绍
- 可以封装sql对象,包括where条件,order by排序,select哪些字段等等
- 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
- 1
- 核心API
- eq 等于
- ne 不等于
- gt 大于
- ge 大于等于
- lt 小于
- le 小于等于
- or 拼接or
- between 两个值中间
- notBetween 不在两个值中间
第5集 QueryWrapper模糊查询和其他API讲解
简介:介绍QueryWrapper的模糊查询和其他API讲解
- QueryWrapper介绍(基于上集)
- 可以封装sql对象,包括where条件,order by排序,select哪些字段等等
- 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
- 1
- 核心API
- like 模糊匹配
- notLike 不像
- likeLeft 左匹配
- likeRight 右边匹配
- isNull 字段为空
- in in查询
- groupBy 分组
- orderByAsc 升序
- orderByDesc 降序
- having having查询
/***
* 新增
*/
@Test
public void testAdd(){
BannerDO bannerDO = new BannerDO();
bannerDO.setImg("xxxxx");
bannerDO.setUrl("xdcalss.net");
bannerMapper.insert(bannerDO);
log.info("轮播图:{}",bannerDO);
}
@Test
public void testDeleteId(){
int rows = bannerMapper.deleteById(4);
log.info("rows:{}",rows);
}
@Test
public void testDeleteByMap(){
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("weight",12);
columnMap.put("url","bbb");
int rows = bannerMapper.deleteByMap(columnMap);
log.info("rows:{}",rows);
}
/**
* 更新
*/
@Test
public void testUpdate(){
BannerDO bannerDO = new BannerDO();
bannerDO.setUrl("taobao.com");
int rows = bannerMapper.update(bannerDO,new QueryWrapper<BannerDO>().eq("id",1));
log.info("rows:{}",rows);
}
/**
* 更新
*/
@Test
public void testUpdateWrapper(){
UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.set("url","aaaa.com");
updateWrapper.eq("id",1);
int rows = bannerMapper.update(null,updateWrapper);
log.info("rows:{}",rows);
}
/**
* * eq 等于
* * ne 不等于
* * gt 大于
* * ge 大于等于
* * lt 小于
* * le 小于等于
* * or 拼接or
* * between 两个值中间
* * notBetween 不在两个值中间
*/
@Test
public void testQueryWrapper1(){
//SELECT id,img,url,weight AS weightAAA FROM banner WHERE (id = ? AND url <> ?)
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("id",1);
queryWrapper.or();
queryWrapper.ne("url","bbbc.com");
bannerMapper.selectList(queryWrapper);
}
/**
* * like 模糊匹配
* * notLike 不像
* * likeLeft 左匹配
* * likeRight 右边匹配
* * isNull 字段为空
* * in in查询
* * groupBy 分组
* * orderByAsc 升序
* * orderByEdsc 降序
* * having having查询
*/
@Test
public void testQueryWrapper2(){
QueryWrapper queryWrapper = new QueryWrapper();
// queryWrapper.like("url","bbb");
// queryWrapper.notLike("img","cccc");
//SELECT id,img,url,weight AS weightAAA FROM banner WHERE (url LIKE ? AND img NOT LIKE ?)
//queryWrapper.likeLeft("url","bbb");
//queryWrapper.likeRight("img","cccc");
queryWrapper.isNull("img");
queryWrapper.in("url",Arrays.asList("aaaa","bbbb"));
queryWrapper.orderByDesc("id");
//SELECT id,img,url,weight AS weightAAA FROM banner WHERE (img IS NULL AND url IN (?,?)) ORDER BY id DESC
bannerMapper.selectList(queryWrapper);
}
/**
* 测试分页功能
*/
@Test
public void testPage(){
// QueryWrapper<BannerDO> queryWrapper = new QueryWrapper();
// queryWrapper.eq("weight",4);
//第一页,每页3条, 如果是第一页则直接一个问号,获取条数
Page<BannerDO> page = new Page<>(2,2);
IPage<BannerDO> iPage = bannerMapper.selectPage(page,null);
log.info("总条数:{}",iPage.getTotal());
log.info("总页数:{}",iPage.getPages());
log.info("数据:{}",iPage.getRecords());
}
第6集 新版MybatisPlus插件配置案例实战之分页插件
简介: 案例实战 Mybatis plus 分页插件配置
- 项目配置分页
@Configuration
public class MybatisPlusPageConfig {
/* 旧版本配置
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}*/
/**
* 新的分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
- 测试分页
/***
* 测试分页
*/
@Test
public void testPage() {
// QueryWrapper<BannerDO> queryWrapper = new QueryWrapper<>();
Page<BannerDO> bannerDOPage = new Page<>(1, 2);
IPage<BannerDO> iPage = bannerMapper.selectPage(bannerDOPage, null);
log.info("总条数:{}", iPage.getTotal());
log.info("总页数:{}", iPage.getPages());
log.info("数据:{}", iPage.getRecords());
}
第六章 MybatisPlus⾼⼿进阶实战
第1集 案例实战 MybatisPlus 自定义xml的sql脚本
简介: 案例实战 Mybatis plus 自定义sql脚本
- 新建xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--这个名称空间是Mapper接口的路径,记得修改-->
<mapper namespace="net.classes.mapper.BannerMapper">
</mapper>
- 配置文件告诉mapper.xml路径(如果采用默认路径可以不配)
#配置plus打印sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#默认配置路径
mybatis-plus.mapper-locations=classpath*:/mapper/*Mapper.xml
第2集 MybatisPlus全局配置文件案例讲解
简介:讲解 Mybatis plus全局配置案例
- 配置Myabits的全局配置文件
- 注意:config-location和configuration不能同时出现,需要注释配置文件里的相关配置
#配置文件
server.port=8081
#==============================数据库相关配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.114:3306/xd_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=xdclass.net
#开启控制台打印sql
#mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#配置mybatis plus打印sql日志
#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#配置最新全局配置文件!!!!
mybatis-plus.config-location = classpath:mybatis-config.xml
- 创建mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--控制台输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
</configuration>
- 配置文件配置 自定义sql的包扫描
mybatis-plus.type-aliases-package= net.xdclass.shop.model
- XML改为
<!--旧-->
<select id="list" resultType="net.xdclass.shop.model.BannerDO">
select * from banner
</select>
<!--新-->
<select id="list" resultType="BannerDO">
select * from banner
</select>
- mybatis plus下划线转驼峰配置,默认就是true
mybatis-plus.configuration.map-underscore-to-camel-case=true
- 配置全局默认主键类型,实体类就不用加 @TableId(value = “id”, type = IdType.AUTO)
mybatis-plus.global-config.db-config.id-type=auto
第3集 SQL性能优化面试题之Mybatis Plus指定select字段查询
简介: 性能优化之指定select字段查询
- 面试题:select * 和 select 指定字段的区别
- 网络IO问题
- select * 会查出所有的字段,有些是不需要的,当应用程序和服务器不在同一个局域网时,字段过多会影响网络传输的性能
- 索引问题
- 在 指定字段有索引的情况下,mysql是可以不用读data,直接使用index里面的值就返回结果的。 但是一旦用了select *,就会有其他列需要从磁盘中读取才会返回结果,这样就造成了额外的性能开销
- 网络IO问题
- MybatisPlus指定查询字段
bannerMapper.selectList(new QueryWrapper<BannerDO>().select("id","name"));
第4集 Mybatis Plus的探索-ActiveRecord使用
简介: 讲解什么是ActiveRecord和使用
- 什么是ActiveRecord(只做简单了解即可)
- Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
- Mybatis Plus对AR有一定支持, 在MP中开启AR,仅需要实体类继承Model类即可
@Data
//表名映射,用于新增才需要
@TableName("banner")
public class BannerDO extends Model<BannerDO> {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String img;
private String url;
private Integer weight;
}
- 使用
/***
* 领域活动
*/
@Test
public void testModelAR() {
BannerDO bannerDO = new BannerDO();
List<BannerDO> bannerDOS = bannerDO.selectList(null);
bannerDOS.stream().forEach(obj-> System.out.println(obj));
}
- 使用建议
- 业务逻辑比较简单,当类基本上和数据库中的表一一对应时, ActiveRecord是非常方便的, 即业务逻辑大多数是对单表操作,简单,直观 一个类就包括了数据访问和业务逻辑.
- ActiveRecord虽然有业务逻辑, 但基本上都是基于单表的. 跨表逻辑一般会放到当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script)中.
- 如果对象间的关联越来越多, 你的事务脚本越来越庞大, 重复的代码越来越多, 就不建议使用了
- 模型容易混乱,ActiveRecord保存了数据, 使它有时候看上去像数据传输对象(DTO). 但是ActiveRecord有数据库访问能力, 所以所以分布式或者大型项目基本不用
- POJO: model/domain/dto/vo/bo/do
第5集 数据库高并发更新必备技能之乐观锁
简介: 讲解高并发里面的乐观锁介绍
- 什么是乐观锁
每次去拿数据的时候都认为别人不会修改,更新的时候会判断是别人是否回去更新数据,通过版本来判断,如果数据被修改了就拒绝更新
Java里面大量使用CAS, CAS这个是属于乐观锁,性能较悲观锁有很大的提高
AtomicXXX 等原子类底层就是CAS实现,一定程度比synchonized好,因为后者是悲观锁
小结:悲观锁适合写操作多的场景,乐观锁适合读操作多的场景,乐观锁的吞吐量会比悲观锁多
- 数据库的乐观锁
大多是基于数据版本 (Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通
过为数据库表增加一个 “version” 字段来 实现。 读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据,库表对应记录的当前版本信息进行比对,如果提交的数据 版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据
第6集 Mybatis Plus高手系列之乐观锁插件实战
简介: 讲解MybatisPlus乐观锁插件使用
- Mybatis Plus里面自带一个插件,可以帮我们轻松实现乐观锁
- 使用
- 实体类增加version属性配置
@Version
private Integer version;
- 数据库增加version版本字段
CREATE TABLE `banner` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`img` varchar(524) DEFAULT NULL COMMENT '图片',
`url` varchar(524) DEFAULT NULL COMMENT '跳转地址',
`weight` int(11) DEFAULT NULL COMMENT '权重',
`version` int(11) DEFAULT '1' COMMENT '乐观锁版本号',
`deleted` int(11) DEFAULT '0' COMMENT '0是未删除,1是已经删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4;
- 增加乐观锁插件
/**
* 分页假乐观锁
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
- 使用
/***
* 乐观锁测试
*/
@Test
public void testOptimi() {
BannerDO bannerDO = new BannerDO();
bannerDO.setVersion(2);//旧版本号,即查询出来的版本号
bannerDO.setId(1);
bannerDO.setUrl("baidu.com");
bannerMapper.updateById(bannerDO);
}
- 注意
- 乐观锁数据类型支持int、integer、long、timestamp
- 仅支持updateById和update方法
第7集 Mybatis Plus高手系列之逻辑删除配置实战
简介: 讲解MybatisPlus 逻辑删除配置
- 什么是逻辑删除
很多互联网公司在数据库设计规范中都加入了逻辑删除的强制规定,运营人员可以分析和审查数据,也方便将数据沉淀下来用于商业分析
比如用户删除了订单,只不过是更新了标记,不会真正的物理删除。
- 数据量过多,也会采用数据仓库,通过监听应用数据库的数据数据变化,进行迁移到数据仓库
- MybatisPlus如何使用
- 数据库增加deleted字段,0是未删除,1表示删除
- 实体类增加属性配置@TableLogic 或者 在配置文件增加指定
// @TableLogic
private Integer deleted;
- 配置文件新增配置
#删除是1
mybatis-plus.global-config.db-config.logic-delete-value=1
#未删除是0
mybatis-plus.global-config.db-config.logic-not-delete-value=0
#如果java实体类没加注解@TableLogic,则可以配置这个,推荐这里配置
mybatis-plus.global-config.db-config.logic-delete-field=deleted
- 验证
- deleteById删除后就是,结果就是更新 字段
- 查询的时候会自动拼接上deleted=0的检索条件
第七章 提效神器之代码⾃动⽣成MybatisPlus-Generator Lombok
第1集 项目引入Mybatis-plus-generator代码自动生成工具
简介:介绍Mybatis-plus-generator代码自动化生成工具
- Mybatis-plus-generator介绍
- AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
- 底层是模板引擎技术,可以自定义生成的java类模板
- 大家以前或多或少用过基础版mybatis-genarator
- 进阶版mybatis-plus-genarator实战
- 添加依赖
<!-- 代码自动生成依赖 begin -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!-- velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<!-- 代码自动生成依赖 end-->
- 代码(标记TODO的记得修改)
package db;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.platform.commons.util.StringUtils;
import java.util.Scanner;
public class MyBatisPlusGenerator {
public static void main(String[] args) {
//1. 全局配置
GlobalConfig config = new GlobalConfig();
// 是否支持AR模式
config.setActiveRecord(true)
// 作者
.setAuthor("gaobei")
// 生成路径,最好使用绝对路径,window路径是不一样的
//TODO TODO TODO TODO
.setOutputDir("/Users/class/Desktop/demo/src/main/java")
// 文件覆盖
.setFileOverride(true)
// 主键策略
.setIdType(IdType.AUTO)
.setDateType(DateType.ONLY_DATE)
// 设置生成的service接口的名字的首字母是否为I,默认Service是以I开头的
.setServiceName("%sService")
//实体类结尾名称
.setEntityName("%sDO")
//生成基本的resultMap
.setBaseResultMap(true)
//不使用AR模式
.setActiveRecord(false)
//生成基本的SQL片段
.setBaseColumnList(true);
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
// 设置数据库类型
dsConfig.setDbType(DbType.MYSQL)
.setDriverName("com.mysql.cj.jdbc.Driver")
//TODO TODO TODO TODO
.setUrl("jdbc:mysql://127.0.0.1:3306/product?useSSL=false")
.setUsername("root")
.setPassword("123456");
//3. 策略配置globalConfiguration中
StrategyConfig stConfig = new StrategyConfig();
//全局大写命名
stConfig.setCapitalMode(true)
// 数据库表映射到实体的命名策略
.setNaming(NamingStrategy.underline_to_camel)
//使用lombok
.setEntityLombokModel(true)
//使用restcontroller注解
.setRestControllerStyle(true)
// 生成的表, 支持多表一起生成,以数组形式填写
//TODO TODO TODO TODO 两个方式,直接写,或者使用命令行输入
//.setInclude("product","product_task","banner");
.setInclude(scanner("表名,多个英文逗号分割").split(","));
//4. 包名策略配置
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent("net.classes")
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("model")
.setXml("mapper");
//5. 整合配置
AutoGenerator ag = new AutoGenerator();
ag.setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig);
//6. 执行操作
ag.execute();
System.out.println("======= Done 相关代码生成完毕 ========");
}
/**
* <p>
* 读取控制台内容
* </p>
*/
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 (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" tip "!");
}
}
第2集 自动化生成代码-加入项目和自动化工具思考
简介:生成的代码加入项目说明和自动化工具思考
- 对比生成的代码进行配置
- 数据库连接和库名称
- 需要生成的表
- 生成的路径
- 拷贝自动生成的代码进入到项目
- model 类拷贝
- mapper 类拷贝
- mapper xml脚本拷贝
- service和controller不拷贝
- 注意
- 使用起来和普通版的mybatis generator一样,但是这个纯代码,不用复杂xml配置
- 任何框架,不要使用过多的侵入或者框架定制化深的内容,防止后续改动耦合性高,成本大
第3集 提效神器-MyBatisPlus课程总结
简介:MyBatisPlus课程总结和应用场景
- 优点
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 缺点
项目映入了第三方包,未来升级存在一定的兼容性问题
社区相对新生-文档缺乏相关的信息, 或者更新不及时
- 项目使用建议
- 任何框架或技术肯定有利也有弊,看的角度和结合团队实际情况
- 高内聚-低解耦肯定是软件设计思想必须要遵守的原则,所以业务代码可以适当使用MyBatisPlus好的功能
- 好用的:通用crud、自动生成工具、分页查询
- 有点耦合但也不错的功能:逻辑删除、乐观锁等
- AR则不怎么建议使用
- 偏业务型项目、管理后端项目等推荐使用,和jpa类似
第八章 后端提效提效神器之接⼝⽂档⾃动⽣成Swagger3和OpenApi规范
第1集 组队吐槽下后端接口文档的那些鸡毛蒜皮和OpenApi规范
简介:接口文档在实际开发中的那些坑和OpenApi规范介绍
- 接口文档
- 谁产生(新手-老手总会认为是浪费时间的工作)
- 接口开发人员,我们后端工程师
- 谁维护(新手-老手总会认为是浪费时间的工作)
- 接口开发人员,我们后端工程师
- 谁使用
- 前端同学
- 测试同学
- 产品经理
- 谁产生(新手-老手总会认为是浪费时间的工作)
- 接口存在的问题
- 接口文档不存在,靠抓包获取
- 接口更换后不及时更新
- 接口文档写错,注解写错
- 自动生成文档工具在跨语言不兼容
- OpenApi规范:声明了用于文档的规范的版本
- 地址:https://github.com/OAI/OpenAPI-Specification
OpenAPI规范经过Reverb Technologies和SmartBear等公司多年的发展,OpenAPI计划拥有该规范(捐赠之后),OpenAPI Initiative在GitHub上托管社区驱动的规范。
规范是一种与语言无关的格式,用于描述RESTful Web服务,应用程序可以解释生成的文件,这样才能生成代码、生成文档并根据其描述的服务创建模拟应用。
开放API规范(OAS)是一种无需编写实际API代码就可以记录API的方法。 这是一种开放源代码格式,可以用来描述API。 在此过程中,我们可以使用JSON或YAML格式。
OpenAPI文档有三个必需的部分或对象,也可以增加其他模块:
1. openapi - OpenAPI规范版本的语义版本号
2. info - 有关API的元数据
3. paths - API的可用路径和操作
第2集 业界里面自动化接口文档生成的解决方案介绍
简介:自动化接口文档生成解决方案介绍
- ApiDoc
- 地址:https://apidocjs.com/
- github: https://github.com/apidoc/apidoc
- 简介:源代码中的注释直接自动生成api接口文档的工具
/**
* @apiGroup Product
* @api {GET} /product/{id} 查询一个产品
* @apiDescription 接口描述xxx
* @apiParam {String} id 产品id(必填*)
* @apiSuccessExample SuccessExample
* HTTP/1.1 200
* {
* id: 'xxx',
* name: 'xxx',
* desc: 'xxxx'
* }
* @apiErrorExample ErrorExample
*/
@GetMapping("/{id}")
public Product detail(@PathVariable String id)
{
return JsonData.buildSuccess();
}
- 优点
- 不入侵代码
- 支持跨语言使用
- 界面友好简洁
- 缺点
- 依赖环境 node/npm
- Swagger 丝袜哥
- 地址:https://swagger.io/tools/swagger-ui/
- 简介:在java代码里面增加注解生成接口文档
- 在代码里面增加注解
RestController
@RequestMapping("api/v1/user")
@Api(tags = "用户模块",value = "用户UserController")
public class UserController {
@Autowired
private BannerService bannerService;
@ApiOperation("分页用户列表")
@GetMapping("list")
public JsonData list(){
List<BannerDO> list = bannerService.list();
return JsonData.buildSuccess(list);
}
}
- 优点
- 支持SpringMVC、SpringBoot、SpringCloud等主流java框架
- 对java代码友好
- 界面简洁
- 国内比较活跃,主要是spring社区带动
- 功能比较多
- 缺点
- 对跨语言支持不友好(可以和knife4j整合解决这个问题)
- 代码需要引入相关依赖包和配置
- 文档相对缺少
第3集 SpringFox3.x和Swagger3.x介绍
简介:SpringFox和自动化接口文档生成工具Swagger介绍
- Swagger介绍
- 基于 OpenAPI 规范(OpenAPI Specification,OAS)构建的开源接口文档自动生成工具,可以让开发人员快速设计、构建、记录以及使用 Rest API
- 版本的说明
- 目前的版本有swagger2.0和3.0
- swagger2于17年停止维护,现在最新的版本为17年发布的 Swagger3(Open Api3)。
- Swagger 主要包含了以下三个部分:
- Swagger Editor:基于浏览器的编辑器,我们可以使用它编写我们 OpenAPI 规范。
- Swagger UI:它会将我们编写的 OpenAPI 规范呈现为交互式的 API 文档,后文我将使用浏览器来查看并且操作我们的 Rest API。
- Swagger Codegen:它可以通过为 OpenAPI(以前称为 Swagger)规范定义的任何 API 生成服务器存根和客户端 SDK 来简化构建过程。
- SpringFox介绍(是 spring 社区维护的一个非官方项目)
- 是一个开源的API Doc的框架,Marty Pitt编写了一个基于Spring的组件swagger-springmvc,用于将swagger集成到springmvc中来, 它的前身是swagger-springmvc,可以将我们的Controller中的方法以文档的形式展现。官方定义为: Automated JSON API documentation for API’s built with Spring。
- 地址:https://github.com/springfox/springfox
- 版本的说明
- SpringFox 3.0.0 发布(突破性的变更版本)
- Spring5,Webflux支持,依赖少
- 支持OpenApi 3.0.3
- 有springboot的整合的starter,使用更便捷
第4集 基于OpenAPi规范-新版SpringBoot2.x整合Swagger3.x
简介:新版Springboot2.x整合Swagger3.x
- SpringBoot添加pom文件依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!--如果SpringBoot版本大于2.3则需要引入下面依赖-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
代码语言:javascript复制启动类添加
@EnableKnife4j
- 配置文件增加配置
spring.application.name=mou-service
# ===== 自定义swagger配置 ===== #
swagger.enable=true
swagger.application-name= ${spring.application.name}
swagger.application-version=1.0
#swagger.application-description=mou平台管理后端接口文档
swagger.application-description=1024shop api info
- 创建配置类
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Component
@EnableOpenApi
@ConfigurationProperties("swagger")
@Data
public class SwaggerConfiguration {
/**
* 是否开启swagger,生产环境一般关闭,所以这里定义一个变量
*/
private Boolean enable;
/**
* 项目应用名
*/
private String applicationName;
/**
* 项目版本信息
*/
private String applicationVersion;
/**
* 项目描述信息
*/
private String applicationDescription;
@Bean
public Docket docket() {
return new Docket(DocumentationType.OAS_30).pathMapping("/")
// 定义是否开启swagger,false为关闭,可以通过变量控制,线上关闭
.enable(enable)
//配置api文档元信息
.apiInfo(apiInfo())
// 选择哪些接口作为swagger的doc发布
.select()
//apis() 控制哪些接口暴露给swagger,
// RequestHandlerSelectors.any() 所有都暴露
// RequestHandlerSelectors.basePackage("net.classes.*") 指定包位置
// withMethodAnnotation(ApiOperation.class)标记有这个注解 ApiOperation
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title(applicationName).description(applicationDescription).contact(new Contact("开发人员", "https://baidu.com", "652133917@qq.com")).version(applicationVersion).build();
}
}
- 新版访问路径(和旧版的不一样)
- http://localhost:8081/swagger-ui/index.html
- 注意:如果访问不成功,记得看是否有拦截器拦截了相关资源,配置不拦截即可
第5集 快速掌握Swagger3.x常用注解讲解和配置
简介:新版Springboot2.x整合Swagger3.x
- 用户模块相关接口文档配置
- @Api 模块配置,用在controller类,描述API接口
@Api(tags = "用户模块",value = "用户UserController")
public class UserController {
}
- @ApiOperation 接口配置,用在方法上,描述接口方法
@ApiOperation("分页用户列表")
@GetMapping("list")
public JsonData list(){
return JsonData.buildSuccess();
}
- @ApiParam 方法参数配置,用在入参上面,描述参数
@ApiOperation("用户登录")
@PostMapping("login")
public JsonData login(
@ApiParam(name = "phone", value = "手机号",example = "13888888888")
@RequestParam("phone") String phone,
@ApiParam(name = "pwd", value = "密码",example = "123456")
@RequestParam("pwd")String pwd){
return JsonData.buildSuccess();
}
- restful例子
@ApiOperation("删除用户")
@DeleteMapping("/delete/{id}")
public JsonData deleteById(@PathVariable int id) {
return JsonData.buildSuccess();
}
- @ApiIgnore 忽略此接口不生成文档
@ApiIgnore
@ApiOperation("删除用户")
@DeleteMapping("/delete/{id}")
public JsonData deleteById(@PathVariable int id) {
return JsonData.buildSuccess();
}
第九章 玩转Swagger3.0接⼝⽂档案例实战进阶
第1集 Swagger3.x对象注解ApiModel讲解
简介:讲解Swagger3.x对象注解ApiModel讲解
- APiModel和ApiModelProperty对象注解介绍
- @ApiModel()
- 用于类 表示对类进行说明,用于参数用实体类接收,value–表示对象名,description–描述
- 这种一般用在post创建的时候,使用对象提交这样的场景
- @ApiModelProperty()
- 用于方法,字段; 表示对model属性的说明或者数据操作更改
- value–字段说明
- name–重写属性名字
- dataType–重写属性类型
- required–是否必填
- example–举例说明
- hidden–隐藏
- @ApiModel()
@Data
@ApiModel("用户基本信息")
public class SaveUserRequest {
private int age;
private String pwd;
@ApiModelProperty(value ="【必填】邮箱",required = true)
private String email;
@ApiModelProperty("【必填】手机号")
private String phone;
@ApiModelProperty(value="创建时间")
private Date createTime;
}
第2集 Swagger3.x响应结果ApiResponse和测试面板
简介:讲解Swagger3.x响应接口和测试面板
- @ApiResponse 描述接口响应
@ApiOperation("用户登录")
@PostMapping("login")
@ApiResponses({
@ApiResponse(responseCode = CodeStatus.SUCCESS, description = "保存成功"),
@ApiResponse(responseCode = CodeStatus.FAIL, description = "保存失败")
})
public JsonData login(
@ApiParam(name = "phone", value = "手机号",example = "13888888888")
@RequestParam("phone") String phone,
@ApiParam(name = "pwd", value = "密码",example = "123456")
@RequestParam("pwd")String pwd){
return JsonData.buildSuccess();
}
第3集 Swagger3.x和项目整合的注意事项
简介:项目中使用Swagger整合接口文档常见问题
- 明确接口的Http请求方式
- 一个接口使用@RequestMapping会生成多个文档
- 线上不要开启接口文档
- 考虑团队当下和未来是否可以一直用,没有说百分百好用,缺点和优点都要知道