资料下载
<code style="margin-left:0">https://atgfwacnz-my.sharepoint.com/:f:/g/personal/gtfonedriver_365vip_eu_org/EiXUA7XZ5dBEpNS0o_m9og0BCib9dy2vQjztVuJbf4APMg?e=HNwCS2</code>
第一章 开发环境准备和新版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仓库,不⽤更换地址
<code style="margin-left:0"> <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></code>
第二章 写代码⻜的感觉-急速上⼿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对象,只要加上注解就行
- 使用方式
- 项目添加依赖进行版本管理
<code style="margin-left:0"> <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文件--></code>
- 添加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)
<code style="margin-left:0">@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 = "广东省广州市"; }</code>
第4集 Lombok插件玩转NonNull+构造函数注解ArgsConstructor实战
简介:讲解Lombok非空判断和构造函数注解
- @NonNull
- 作用于方法上或者属性,用于非空判断,如果为空则抛异常
<code style="margin-left:0"> public void login(@NotNull String pwd){ }</code>
- @NoArgsConstructor
- 生成无参构造器
- @AllArgsConstructor
- 生成全参构造器
- @RequiredArgsConstructor
- 指定参数的构造函数,有以下的特征的字段
- final类型未被初始化的属性, 标记了@NonNull的属性
- 注意:@NoArgsConstructor不能加
- 指定参数的构造函数,有以下的特征的字段
第5集 知其然而知其所以然-Lombok插件原理-对比反射技术
简介:讲解JSR介绍和lombok原理讲解
- 光会用就行了?肯定是不行的啊,知其所以然才行的,实现这样神器的效果是咋做的?
- 熟悉Java自定义注解的同学已经猜到是: JSR 269插件化注解处理
<code style="margin-left:0">JSR 269: Pluggable Annotation Processing API 实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件 地址:https://www.jcp.org/en/jsr/detail?id=269</code>
- 科普
<code style="margin-left:0">JSR是Java Specification Requests的缩写,意思是Java 规范提案。 是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。 任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。</code>
- Lombok解析流程如下
<code style="margin-left:0">Javac 解析成AST抽象语法树后, Lombok根据自己编写的注解处理器,动态地修改 AST增加新的节点(即Lombok自定义注解所需要生成的代码),最终生成JVM可执行的字节码Class文件 可以看编译后的在target目录下的class文件</code>
- 能实现上述效果的还有一个反射技术,那两个对比如何?
<code style="margin-left:0">使用Annotation Processing自定义注解是在编译阶段进行修改 JDK的反射技术是在运行时动态修改 结论:反射更加灵活一些但是带来的性能损耗更加大</code>
第三章 精通Lombok插件+Java面试核心巩固
第1集 Lombok插件玩转Debug必备利器toString()注解
简介:讲解lombok的toString()注解
- java bean对象为啥要重新toString方法?
- List或者其他集合调试不方便
- 控制台或者日志输出对象,默认打印的是内存地址
- @ToString
- 作用于类,覆盖默认的toString()方法
- 不包括某个字段
<code style="margin-left:0">@ToString(exclude = {"age"})</code>
- 只输出某个字段
<code style="margin-left:0">@ToString(of = {"name"})</code>
第2集 Java核心面试题-重温hashcode和equal方法
简介:重温Java核心知识hashcode和equal方法
- 为什么对象要重写hashcode和equal方法?
- HashCode⽅法
- 顶级类Object⾥⾯的⽅法,所有类都是继承Object的,返回值int类型
- 根据⼀定的hash规则(存储地址,字段,或者⻓度等),映射成⼀个数值,即散列值
- Equals⽅法
- 顶级类Object⾥⾯的⽅法,所有类都是继承Object的,返回值boolean类型
- 根据⾃定义的匹配规则,⽤于匹配两个对象是否⼀样, ⼀般逻辑是如下
- HashCode⽅法
<code style="margin-left:0"> //判断地址是否⼀样 //⾮空判断和class类型判断 //强转 //对象⾥⾯的字段⼀⼀匹配</code>
解析
如果两个对象相等,那么它们的hashCode()值一定相同(这里的相等是指,通过equals()比较两个对象时返回true)
如果两个对象hashCode()相等,它们并不一定相等。在散列表中hashCode()相等,即两个键值对的哈希值相等。
然而哈希值相等,并不一定能得出键值对相等,就出现所谓的哈希冲突场景,还需判断equals⽅法判断对象是否相等
应用场景:当向集合中插⼊对象时,如何判别在集合中是否已经存在该对象,⽐如Set确保存储对象的 唯⼀,并判断是不是同个对象呢?
<code style="margin-left:0"> 依据hashCode和equals进⾏判断 所以Set存储的对象必须重写这两个⽅法 判断两个对象是否⼀样 ⾸先判断插⼊obj的hashcode值是否存在,hashcode值不存在则直 接插⼊集合 值存在则还需判断equals⽅法判断对象是否相等 </code>
第3集 Lombok插件玩转对象匹配EqualsAndHashCode注解
简介:玩转lombok的EqualsAndHashCode注解
- @EqualsAndHashCode
- 作用于类,覆盖默认的equals和hashCode, 作用于全部属性
- 不包括某个属性
<code style="margin-left:0">@EqualsAndHashCode(exclude = {"age"})</code>
- 只输出某个属性
<code style="margin-left:0">@EqualsAndHashCode(of = {"name"})</code>
第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
<code style="margin-left:0">@Setter/@Getter @NonNull @NoArgsConstructor @AllArgsConstructor @RequiredArgsConstructor @ToString @EqualsAndHashCode @Data @Builder @Log @Slf4j</code>
第四章 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
- 更多特性
<code style="margin-left:0">无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 损耗小:启动即会自动注入基本 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 查询 分页插件支持多种<a href="https://www.mhzhuji.com/kwck/57" class="lar_link lar_link_outgoing" data-linkid="219" data-postid="2681" title="数据库<a href="https://www.mhzhuji.com/kwck/57" class="lar_link lar_link_outgoing" data-linkid="219" data-postid="2681" title="数据库MySQL" rel="nofollow" target="_blank" >MySQL</a>" rel="nofollow" target="_blank" >数据库</a>:支持 <a href="https://www.mhzhuji.com/kwck/57" class="lar_link lar_link_outgoing" data-linkid="219" data-postid="2681" title="数据库MySQL" rel="nofollow" target="_blank" >MySQL</a>、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种<a href="https://www.mhzhuji.com/kwck/57" class="lar_link lar_link_outgoing" data-linkid="219" data-postid="2681" title="数据库MySQL" rel="nofollow" target="_blank" >数据库</a> 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作</code>
- 数据库准备
- 资料里面有数据库,多个表
导入本地自己创建好的数据库
- 资料里面有数据库,多个表
- 新建 class_shop 库
第2集 新版SpringBoot2.X整合MybatisPlus+Lombok插件
简介:使用新版SpringBoot2.x整合MybatisPlus + Lombok
- 新版SpringBoot整合
<code style="margin-left:0"> <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></code>
- 增加数据库配置
<code style="margin-left:0">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</code>
- 建立好包,配置springboot扫描路径
第3集 SpringBoot+Mybatis plus案例商品轮播图整合实战
简介:SpringBoot整合Mybatis plus项目实战
- 基础准备
- 统一接口返回协议-JsonData
<code style="margin-left:0">@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); } }</code>
- BannerDO类编写
<code style="margin-left:0">@Data @TableName("banner")//表名映射 public class BannerDO { private Integer id; private String img; private String url; private Integer weight; }</code>
- 开发controller-
<code style="margin-left:0">@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); } }</code>
- service
<code style="margin-left:0">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<>()); } }</code>
- mapper
<code style="margin-left:0">public interface BannerMapper extends BaseMapper<BannerDO> { }</code>
第4集 集成Spring Boot Test单元测试和控制台sql日志打印
简介:项目集成Spring Boot Test单元测试+控制台数据sql
- 需求分析->设计->开发->测试->上线
- 单元测试: 完成最小的软件设计单元的验证工作,目标是确保模块被正确的编码
- Spring Boot Test 是在Spring Test之上的再次封装, 使用@SpringBootTest后,Spring将加载所有被管理的bean,等同于启动了整个服务
- 项目添加依赖
<code style="margin-left:0"><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency></code>
- 项目新建测试
<code style="margin-left:0">@SpringBootTest(classes = TestApplication.class) @Slf4j class BannerTest { @Autowired private BannerService bannerService; @Test public void testBannerList(){ List<BannerDO> list = bannerService.list(); log.info("轮播图列表:{}",list); } }</code>
- Mybatis plus配置控制台打印日志
<code style="margin-left:0">#配置mybatis plus打印sql日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl</code>
第5集 MybatisPlus核心类BaseMapper介绍
简介:介绍MybaitsPlus核心类BaseMapper
- 核心类介绍: Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
- 方法很多:记住常用的几个就行
<code style="margin-left:0">/** * 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); }</code>
QueryWrapper介绍
- 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
<code style="margin-left:0">List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());</code>
第6集 MybatisPlus多案例查询API实战
简介:介绍MybaitsPlus多案例查询API实战
- 多案例API查询
<code style="margin-left:0">@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); } }</code>
第五章 玩转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 用于定义表的非主键字段
- 属性
<code style="margin-left:0">value 用于定义非主键字段名,用于别名匹配,假如java对象属性和数据库属性不一样 exist 用于指明是否为数据表的字段, true 表示是,false 为不是,假如某个java属性在数据库没对应的字段则要标记为faslse fill 用于指定字段填充策略(FieldFill,用的不多) 字段填充策略:一般用于填充 创建时间、修改时间等字段 FieldFill.DEFAULT 默认不填充 FieldFill.INSERT 插入时填充 FieldFill.UPDATE 更新时填充 FieldFill.INSERT_UPDATE 插入、更新时填充。</code>
第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查询
<code style="margin-left:0">/*** * 新增 */ @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()); }</code>
第6集 新版MybatisPlus插件配置案例实战之分页插件
简介: 案例实战 Mybatis plus 分页插件配置
- 项目配置分页
<code style="margin-left:0">@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; } } </code>
- 测试分页
<code style="margin-left:0"> /*** * 测试分页 */ @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()); }</code>
第六章 MybatisPlus⾼⼿进阶实战
第1集 案例实战 MybatisPlus 自定义xml的sql脚本
简介: 案例实战 Mybatis plus 自定义sql脚本
- 新建xml
<code style="margin-left:0"><?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></code>
- 配置文件告诉mapper.xml路径(如果采用默认路径可以不配)
<code style="margin-left:0">#配置plus打印sql日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #默认配置路径 mybatis-plus.mapper-locations=classpath*:/mapper/*Mapper.xml</code>
第2集 MybatisPlus全局配置文件案例讲解
简介:讲解 Mybatis plus全局配置案例
- 配置Myabits的全局配置文件
- 注意:config-location和configuration不能同时出现,需要注释配置文件里的相关配置
<code style="margin-left:0">#配置文件 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</code>
- 创建mybatis-config.xml
<code style="margin-left:0"><?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> </code>
- 配置文件配置 自定义sql的包扫描
<code style="margin-left:0">mybatis-plus.type-aliases-package= net.xdclass.shop.model</code>
- XML改为
<code style="margin-left:0"><!--旧--> <select id="list" resultType="net.xdclass.shop.model.BannerDO"> select * from banner </select> <!--新--> <select id="list" resultType="BannerDO"> select * from banner </select></code>
- mybatis plus下划线转驼峰配置,默认就是true
<code style="margin-left:0">mybatis-plus.configuration.map-underscore-to-camel-case=true</code>
- 配置全局默认主键类型,实体类就不用加 @TableId(value = “id”, type = IdType.AUTO)
<code style="margin-left:0">mybatis-plus.global-config.db-config.id-type=auto</code>
第3集 SQL性能优化面试题之Mybatis Plus指定select字段查询
简介: 性能优化之指定select字段查询
- 面试题:select * 和 select 指定字段的区别
- 网络IO问题
- select * 会查出所有的字段,有些是不需要的,当应用程序和服务器不在同一个局域网时,字段过多会影响网络传输的性能
- 索引问题
- 在 指定字段有索引的情况下,mysql是可以不用读data,直接使用index里面的值就返回结果的。
但是一旦用了select *,就会有其他列需要从磁盘中读取才会返回结果,这样就造成了额外的性能开销
- 在 指定字段有索引的情况下,mysql是可以不用读data,直接使用index里面的值就返回结果的。
- 网络IO问题
- MybatisPlus指定查询字段
<code style="margin-left:0">bannerMapper.selectList(new QueryWrapper<BannerDO>().select("id","name"));</code>
第4集 Mybatis Plus的探索-ActiveRecord使用
简介: 讲解什么是ActiveRecord和使用
- 什么是ActiveRecord(只做简单了解即可)
- Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
- Mybatis Plus对AR有一定支持, 在MP中开启AR,仅需要实体类继承Model类即可
<code style="margin-left:0">@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; }</code>
- 使用
<code style="margin-left:0"> /*** * 领域活动 */ @Test public void testModelAR() { BannerDO bannerDO = new BannerDO(); List<BannerDO> bannerDOS = bannerDO.selectList(null); bannerDOS.stream().forEach(obj-> System.out.println(obj)); }</code>
- 使用建议
- 业务逻辑比较简单,当类基本上和数据库中的表一一对应时, ActiveRecord是非常方便的, 即业务逻辑大多数是对单表操作,简单,直观 一个类就包括了数据访问和业务逻辑.
- ActiveRecord虽然有业务逻辑, 但基本上都是基于单表的. 跨表逻辑一般会放到当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script)中.
- 如果对象间的关联越来越多, 你的事务脚本越来越庞大, 重复的代码越来越多, 就不建议使用了
- 模型容易混乱,ActiveRecord保存了数据, 使它有时候看上去像数据传输对象(DTO). 但是ActiveRecord有数据库访问能力, 所以所以分布式或者大型项目基本不用
- POJO: model/domain/dto/vo/bo/do
第5集 数据库高并发更新必备技能之乐观锁
简介: 讲解高并发里面的乐观锁介绍
- 什么是乐观锁
<code style="margin-left:0">每次去拿数据的时候都认为别人不会修改,更新的时候会判断是别人是否回去更新数据,通过版本来判断,如果数据被修改了就拒绝更新 Java里面大量使用CAS, CAS这个是属于乐观锁,性能较悲观锁有很大的提高 AtomicXXX 等原子类底层就是CAS实现,一定程度比synchonized好,因为后者是悲观锁 小结:悲观锁适合写操作多的场景,乐观锁适合读操作多的场景,乐观锁的吞吐量会比悲观锁多</code>
- 数据库的乐观锁
<code style="margin-left:0">大多是基于数据版本 (Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通 过为数据库表增加一个 “version” 字段来 实现。 读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据,库表对应记录的当前版本信息进行比对,如果提交的数据 版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据</code>
第6集 Mybatis Plus高手系列之乐观锁插件实战
简介: 讲解MybatisPlus乐观锁插件使用
- Mybatis Plus里面自带一个插件,可以帮我们轻松实现乐观锁
- 使用
- 实体类增加version属性配置
<code style="margin-left:0">@Version private Integer version;</code>
- 数据库增加version版本字段
<code style="margin-left:0">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;</code>
- 增加乐观锁插件
<code style="margin-left:0"> /** * 分页假乐观锁 * @return */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); //乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }</code>
- 使用
<code style="margin-left:0"> /*** * 乐观锁测试 */ @Test public void testOptimi() { BannerDO bannerDO = new BannerDO(); bannerDO.setVersion(2);//旧版本号,即查询出来的版本号 bannerDO.setId(1); bannerDO.setUrl("baidu.com"); bannerMapper.updateById(bannerDO); }</code>
- 注意
- 乐观锁数据类型支持int、integer、long、timestamp
- 仅支持updateById和update方法
第7集 Mybatis Plus高手系列之逻辑删除配置实战
简介: 讲解MybatisPlus 逻辑删除配置
- 什么是逻辑删除
<code style="margin-left:0">很多互联网公司在数据库设计规范中都加入了逻辑删除的强制规定,运营人员可以分析和审查数据,也方便将数据沉淀下来用于商业分析 比如用户删除了订单,只不过是更新了标记,不会真正的物理删除。</code>
- 数据量过多,也会采用数据仓库,通过监听应用数据库的数据数据变化,进行迁移到数据仓库
- MybatisPlus如何使用
- 数据库增加deleted字段,0是未删除,1表示删除
- 实体类增加属性配置@TableLogic 或者 在配置文件增加指定
<code style="margin-left:0">// @TableLogic private Integer deleted;</code>
- 配置文件新增配置
<code style="margin-left:0">#删除是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</code>
- 验证
- 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实战
- 添加依赖
<code style="margin-left:0"> <!-- 代码自动生成依赖 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--></code>
- 代码(标记TODO的记得修改)
<code style="margin-left:0">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 + "!"); } } </code>
第2集 自动化生成代码-加入项目和自动化工具思考
简介:生成的代码加入项目说明和自动化工具思考
- 对比生成的代码进行配置
- 数据库连接和库名称
- 需要生成的表
- 生成的路径
- 拷贝自动生成的代码进入到项目
- model 类拷贝
- mapper 类拷贝
- mapper xml脚本拷贝
- service和controller不拷贝
- 注意
- 使用起来和普通版的mybatis generator一样,但是这个纯代码,不用复杂xml配置
- 任何框架,不要使用过多的侵入或者框架定制化深的内容,防止后续改动耦合性高,成本大
第3集 提效神器-MyBatisPlus课程总结
简介:MyBatisPlus课程总结和应用场景
- 优点
<code style="margin-left:0">无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作</code>
- 缺点
<code style="margin-left:0">项目映入了第三方包,未来升级存在一定的兼容性问题 社区相对新生-文档缺乏相关的信息, 或者更新不及时</code>
- 项目使用建议
- 任何框架或技术肯定有利也有弊,看的角度和结合团队实际情况
- 高内聚-低解耦肯定是软件设计思想必须要遵守的原则,所以业务代码可以适当使用MyBatisPlus好的功能
- 好用的:通用crud、自动生成工具、分页查询
- 有点耦合但也不错的功能:逻辑删除、乐观锁等
- AR则不怎么建议使用
- 偏业务型项目、管理后端项目等推荐使用,和jpa类似
第八章 后端提效提效神器之接⼝⽂档⾃动⽣成Swagger3和OpenApi规范
第1集 组队吐槽下后端接口文档的那些鸡毛蒜皮和OpenApi规范
简介:接口文档在实际开发中的那些坑和OpenApi规范介绍
- 接口文档
- 谁产生(新手-老手总会认为是浪费时间的工作)
- 接口开发人员,我们后端工程师
- 谁维护(新手-老手总会认为是浪费时间的工作)
- 接口开发人员,我们后端工程师
- 谁使用
- 前端同学
- 测试同学
- 产品经理
- 谁产生(新手-老手总会认为是浪费时间的工作)
- 接口存在的问题
- 接口文档不存在,靠抓包获取
- 接口更换后不及时更新
- 接口文档写错,注解写错
- 自动生成文档工具在跨语言不兼容
- OpenApi规范:声明了用于文档的规范的版本
- 地址:https://github.com/OAI/OpenAPI-Specification
<code style="margin-left:0">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的可用路径和操作</code>
第2集 业界里面自动化接口文档生成的解决方案介绍
简介:自动化接口文档生成解决方案介绍
- ApiDoc
- 地址:https://apidocjs.com/
- github: https://github.com/apidoc/apidoc
- 简介:源代码中的注释直接自动生成api接口文档的工具
<code style="margin-left:0">/** * @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(); }</code>
- 优点
- 不入侵代码
- 支持跨语言使用
- 界面友好简洁
- 缺点
- 依赖环境 node/npm
- Swagger 丝袜哥
- 地址:https://swagger.io/tools/swagger-ui/
- 简介:在java代码里面增加注解生成接口文档
- 在代码里面增加注解
<code style="margin-left:0">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); } }</code>
- 优点
- 支持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文件依赖
<code style="margin-left:0"><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></code>
<code style="margin-left:0">启动类添加 @EnableKnife4j</code>
- 配置文件增加配置
<code style="margin-left:0">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 </code>
- 创建配置类
<code style="margin-left:0">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(); } }</code>
- 新版访问路径(和旧版的不一样)
- http://localhost:8081/swagger-ui/index.html
- 注意:如果访问不成功,记得看是否有拦截器拦截了相关资源,配置不拦截即可
第5集 快速掌握Swagger3.x常用注解讲解和配置
简介:新版Springboot2.x整合Swagger3.x
- 用户模块相关接口文档配置
- @Api 模块配置,用在controller类,描述API接口
<code style="margin-left:0"> @Api(tags = "用户模块",value = "用户UserController") public class UserController { }</code>
- @ApiOperation 接口配置,用在方法上,描述接口方法
<code style="margin-left:0"> @ApiOperation("分页用户列表") @GetMapping("list") public JsonData list(){ return JsonData.buildSuccess(); }</code>
- @ApiParam 方法参数配置,用在入参上面,描述参数
<code style="margin-left:0"> @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(); }</code>
- restful例子
<code style="margin-left:0"> @ApiOperation("删除用户") @DeleteMapping("/delete/{id}") public JsonData deleteById(@PathVariable int id) { return JsonData.buildSuccess(); }</code>
- @ApiIgnore 忽略此接口不生成文档
<code style="margin-left:0"> @ApiIgnore @ApiOperation("删除用户") @DeleteMapping("/delete/{id}") public JsonData deleteById(@PathVariable int id) { return JsonData.buildSuccess(); }</code>
第九章 玩转Swagger3.0接⼝⽂档案例实战进阶
第1集 Swagger3.x对象注解ApiModel讲解
简介:讲解Swagger3.x对象注解ApiModel讲解
- APiModel和ApiModelProperty对象注解介绍
- @ApiModel()
- 用于类 表示对类进行说明,用于参数用实体类接收,value–表示对象名,description–描述
- 这种一般用在post创建的时候,使用对象提交这样的场景
- @ApiModelProperty()
- 用于方法,字段; 表示对model属性的说明或者数据操作更改
- value–字段说明
- name–重写属性名字
- dataType–重写属性类型
- required–是否必填
- example–举例说明
- hidden–隐藏
- @ApiModel()
<code style="margin-left:0">@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; }</code>
第2集 Swagger3.x响应结果ApiResponse和测试面板
简介:讲解Swagger3.x响应接口和测试面板
- @ApiResponse 描述接口响应
<code style="margin-left:0">@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(); }</code>
第3集 Swagger3.x和项目整合的注意事项
简介:项目中使用Swagger整合接口文档常见问题
- 明确接口的Http请求方式
- 一个接口使用@RequestMapping会生成多个文档
- 线上不要开启接口文档
- 考虑团队当下和未来是否可以一直用,没有说百分百好用,缺点和优点都要知道
未经允许不得转载:木盒主机 » mybatisplus+swagger【后端专题】