资料下载

链接: https://pan.baidu.com/s/1U0T2-mKLBA7GkgTP91zaXA 提取码: rdvs 

第一章 开发环境准备和新版SpringBoot2.X项⽬创建

第1集 开发环境准备和新版SpringBoot2.X项⽬创建

简介:开发环境准备和说明

  • 必备基础环境:JDK8或者JDK11版本 + Maven3.5(采⽤默
    认) + IDEA旗舰版 + Mysql5.7以上版本

    • 不要⽤JDK11以上,⾮⼤规模的LTS版本且多数软件不⽀持
    • 2021~2024年内,JDK11会是⼤规模流⾏
  • 操作系统:Win10或者Mac苹果

  • 创建新版SpringBoot2.X项⽬

  • 注意: 有些包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类型
      • 根据⾃定义的匹配规则,⽤于匹配两个对象是否⼀样, ⼀般逻辑是如下
 //判断地址是否⼀样
  //⾮空判断和class类型判断
  //强转
  //对象⾥⾯的字段⼀⼀匹配
  • 解析

    如果两个对象相等,那么它们的hashCode()值一定相同(这里的相等是指,通过equals()比较两个对象时返回true)

    如果两个对象hashCode()相等,它们并不一定相等。在散列表中hashCode()相等,即两个键值对的哈希值相等。
    然而哈希值相等,并不一定能得出键值对相等,就出现所谓的哈希冲突场景,还需判断equals⽅法判断对象是否相等

  • 应用场景:当向集合中插⼊对象时,如何判别在集合中是否已经存在该对象,⽐如Set确保存储对象的 唯⼀,并判断是不是同个对象呢?

        依据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 *,就会有其他列需要从磁盘中读取才会返回结果,这样就造成了额外的性能开销
  • 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规范:声明了用于文档的规范的版本
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集 业界里面自动化接口文档生成的解决方案介绍

简介:自动化接口文档生成解决方案介绍

/**
     * @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 丝袜哥
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>

启动类添加
@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();
    }
}

第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–隐藏
@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会生成多个文档
  • 线上不要开启接口文档
  • 考虑团队当下和未来是否可以一直用,没有说百分百好用,缺点和优点都要知道