1、SpringBoot脚手架
- Spring Initializer:https://start.springboot.io/ 、https://start.spring.io/
- 阿里提供的脚手架:https://start.aliyun.com
2、SpringBoot整合Swagger2
Swagger的好处:生成在线API文档、测试数据。
1、引入依赖
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2、编写Swagger配置类
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger2配置类(接口文档)
*
* @author 白豆五
* @version 2022/7/30 19:24
* @since JDK8
*/
@Configuration // 配置类
@EnableSwagger2 // 开启Swagger2
public class Swagger2Config {
/**
* 配置Swagger插件
*/
@Bean
public Docket webApiConfig() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
.paths(Predicates.not(PathSelectors.regex("/admin/.*")))
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build();
}
private ApiInfo webApiInfo() {
return new ApiInfoBuilder()
.title("网站-API文档")
.description("本文档描述了xxx管理系统微服务接口定义")
.version("1.0")
.contact(new Contact("白豆五", "https://blog.csdn.net/qq_46921028", "139999999999@163.com"))
.build();
}
}
3、访问swagger:项目路径/swagger-ui.html
swagger常用注解
1、为实体类(pojo)添加swagger注释:
@ApiModel("xxxPOJO说明")
作用在模型类上,例如 VO、BO、POJO等等。@ApiModelProperty(value = "xxx属性说明",hidden = true)
作用在类方法和属性上,hidden设置为true可以隐藏该属性。
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel("讲师")
public class EduTeacher implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "讲师ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "讲师姓名")
private String name;
@ApiModelProperty(value = "讲师简介")
private String intro;
@ApiModelProperty(value = "讲师资历,一句话说明讲师")
private String career;
@ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
private Integer level;
@ApiModelProperty(value = "讲师头像")
private String avatar;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
@TableLogic // 逻辑删除(表中的数据还有,就是不再显示了)
private Boolean isDeleted;
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
2、为模块(controller)添加swagger注释:
@Api(tags = "xxx模块说明")
描述模块类。@ApiOperation("xxx接口说明")
描述模块类中的接口方法。@ApiParam("xxx参数说明")
描述接口方法的形参。
@Api(tags = "管理员控制器")
@RestController // 向页面返回数据 等同于@Controller+@ResponseBody
@RequestMapping("/sms/adminController") // 请求路径
public class AdminController {
@Autowired
private AdminService adminService;
// GET: /sms/adminController/getAllAdmin/1/3
@ApiOperation("分页带条件查询管理员信息")
@GetMapping("/getAllAdmin/{pageNo}/{pageSize}")
public Result getAllAdmin(
@ApiParam("页码数") @PathVariable("pageNo") Integer pageNo,
@ApiParam("页大小") @PathVariable("pageSize") Integer pageSize,
@ApiParam("管理员名字") String adminName
) {
Page<Admin> pageParm = new Page<>(pageNo, pageSize);
IPage<Admin> adminPage = adminService.getAdminsByOpr(pageParm, adminName);
return Result.ok(adminPage);
}
// POST: /sms/adminController/saveOrUpdateAdmin student
@ApiOperation("添加或者修改管理员信息")
@PostMapping("/saveOrUpdateAdmin")
public Result addOrUpdateAdmin(
@ApiParam("JSON的Admin对象") @RequestBody Admin admin //将json字符串转admin对象
) {
Integer id = admin.getId();
if (id == null || 0 == id) { //如果是新增要对密码加密
admin.setPassword(MD5.encrypt(admin.getPassword()));
}
adminService.saveOrUpdate(admin);
return Result.ok();
}
// DELETE: /sms/adminController/deleteAdmin ids[]
@ApiOperation("删除单个或者多个管理员信息")
@DeleteMapping("/deleteAdmin")
public Result deleteAdmin(@ApiParam("要删除管理员信息的JSON集合,接收的是ids[]") @RequestBody List<Integer> ids) {
adminService.removeByIds(ids);
return Result.ok();
}
}
3、让IntelliJ IDEA 社区版支持Tomcat和SpringBoot
方法:在社区版IDEA里下载插件即可
- 支持Tomcat的插件:Smart Tomcat
- 支持SpringBoot的插件:Spring Initializr and Assistant
4、B站倍速播放
在浏览器控制台输入如下脚本:
document.querySelector('video').playbackRate = 指定的倍速
例如开启2.5倍播放: document.querySelector('video').playbackRate = 2.5
5、EasyExcel
EasyExcel项目地址:https://github.com/alibaba/easyexcel
EasyExcel特点:
- Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是 非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会 OOM 或者JVM频繁的full gc。
- **``EasyExcel`**是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
- EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理 (AnalysisEventListener)。
5.1、 使用EasyExcel进行写操作
1、引入easyexcel依赖:
<dependencies>
<!-- easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
</dependency>
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
</dependencies>
2、创建实体类,要和excel中数据对应:
@Data
public class DemoData {
// 设置Excel表头名称
@ExcelProperty("学生编号")
private Integer sno;
@ExcelProperty("学生姓名")
private String sname;
}
3、实现excel写操作
package com.baidou.demo.excel;
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
/**
* 实现Excel写操作
*
* @author 白豆五
* @version 2022/9/16 19:34
* @since JDK8
*/
public class TestEasyExcel {
public static void main(String[] args) {
// 1、设置写入文件夹地址和excel文件名称
String fileName = "F:\\write.xlsx";
// 2、调用easyexcel里面的方法实现写操作
// write方法两个参数:
// 第一个参数:文件的路径名称
// 第二个参数:实体类的Class
// 往sheet为学生列表中写数据
EasyExcel.write(fileName, DemoData.class).sheet("学生列表").doWrite(getData());
}
/**
* 初始化学生列表
*
* @return
*/
private static List<DemoData> getData() {
List<DemoData> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
DemoData stu = new DemoData();
stu.setSno(i);
stu.setSname("张三"+i);
list.add(stu);
}
return list;
}
}
测试:
写法2:
public static void main(String[] args) throws Exception {
// 写法2,方法二需要手动关闭流
String fileName = "F:\\112.xlsx";
// 这里 需要指定写用哪个class去写
ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("写入方法二").build();
excelWriter.write(data(), writeSheet);
/// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
}
5.2、 使用EasyExcel实现读操作
1、创建实体类,要和excel中数据对应:
@Data
public class DemoData2 {
// 设置列对应属性
@ExcelProperty(value = "学生编号", index = 0)
private Integer sno;
// 设置列对应属性
@ExcelProperty(value = "学生姓名", index = 1)
private String sname;
}
2、创建读取操作的监听
package com.baidou.demo.excel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.Map;
/**
* Excel监听器 (继承阿里写好的excel事件监听器)
*
* @author 白豆五
* @version 2022/9/16 21:13
* @since JDK8
*/
public class ExcelListener extends AnalysisEventListener<DemoData2> {
/**
* 一行一行读取excel内容(他会从第2行读取,因为第一行是表头)
*
* @param data 每行读取的数据
* @param context
*/
@Override
public void invoke(DemoData2 data, AnalysisContext context) {
System.out.println("****" + data);
}
/**
* 读取excel表头内容
*
* @param headMap 表头信息
* @param context
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println("表头:" + headMap);
}
/**
* 读取完成之后执行
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
}
3、实现Excel读操作:
package com.baidou.demo.excel;
import com.alibaba.excel.EasyExcel;
/**
* 实现Excel读操作
*
* @author 白豆五
* @version 2022/9/16 19:34
* @since JDK8
*/
public class TestEasyExcel2 {
public static void main(String[] args) {
// 1、设置要读取excel文件的路径
String fileName = "F:\\write.xlsx";
// 2、excel读操作
//read方法第一个参数:文件路径名
//read方法第二个参数:封装excel实体类
//read方法第三个参数:监听器
EasyExcel.read(fileName,DemoData2.class,new ExcelListener()).sheet().doRead();
}
}
测试:
6、解决MP自定义mapper报BindingException(数据绑定异常)
错误信息如下:(没有找到getPublishCourseInfo方法)
org.apache.ibatis.binding.BindingException:
Invalid bound statement (not found): com.baidou.eduservice.mapper.EduCourseMapper.getPublishCourseInfo
原因一:检查xml文件是否与mapper接口名字对应。
原因二:maven默认加载机制,会加载src\main\java
目录中的.java
文件,其他类型的文件不会加载。
解决方案:
方案①、复制xml到target
目录中。
方案②、将xml文件放到resource
目录中。
方案③、通过配置实现。
(1)在pom.xml中配置节点:
<!--项目打包时会将java目录中的 *.xml 文件也进行打包-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
(2)在SpringBoot核心配置文件application.properties中添加配置:
#配置mapper.xml文件的路径
mybatis-plus.mapper-locations=classpath:com/baidou/eduservice/mapper/xml/*.xml
7、使用maven安装第三方的jar包
项目引入非开源jar包:
- 方式一:把jar包导入项目中;
- 方式二:在本地maven仓库手动安装这个jar包。
1、下载jar,aliyun-java-vod-upload-1.4.11.jar
2、解压文件,使用命令行进入jar所在目录,执行以下代码:
mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.11 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.11.jar
- mvn install:install-file 将jar包安装到本地maven仓库 (固定写法)
- -DgroupId=com.aliyun 组织id
- -DartifactId=aliyun-sdk-vod-upload 项目名
- -Dversion=1.4.11 版本号
- -Dpackaging=jar 依赖的类型,jar包
- -Dfile=aliyun-java-vod-upload-1.4.11.jar 文件名(文件位置)