目录
回顾:
1. springboot自动装配的原理:
2. springboot整合第三方框架: mybatis和pageHelper框架
技术细节:
1.什么是swagger
它就是可以api接口,它可以对你书写的接口进行说明。并以文档的形式存在。
2. 为什么需要使用swagger2的api文档
3 如何使用swagger2
(1)引用swagger的依赖
<!--swagger的依赖引入-->
<dependency>
<groupId>io.github.jianzhichun</groupId>
<artifactId>spring-boot-starter-swagger2</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
(2)配置swagger的信息
package com.zjl.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.HttpRequestHandlerServlet;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration//表示类似于配置文件
public class SwaggerConfig {
@Bean//加在方法上,表示把方法的返回值结果交予spring容器来管理对象,里面封装了接口文档的信息
public Docket docket() {
//select()选择
//后面跟apis(RequestHandlerSelectors.basePackage("com.zjl.controller")).build();只为com.aaa.controller包下的类生成接口文档
Docket docket = new Docket(DocumentationType.SWAGGER_2).groupName("qy165").apiInfo(getApiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.zjl.controller")).build();
return docket;
}
private ApiInfo getApiInfo() {
new Contact("周家乐","http://www.jd.com","110@qq.com");
ApiInfo apiInfo = new ApiInfo("学生管理系统Api文档", "学生管理系统Api文档", "1.0", "http://localhost:8082/doc.html", "周家乐", "AAA有限公司", "https://www.4399.com");
return apiInfo;
}
}
启动工程并访问swagger接口文档的路径
文档有两种形式:
http://ip:port/swagger-ui.html
(3)使用swagger的注解。
1.@Api(tags="") : 加在接口Controller类上,它是对接口类的说明
2.@ApiOperation(value=""):加在接口方法上,他是对接口方法的说明
3.@ApiImplicitParams(:他是对接口所有参数的说明----body参数类型
@ApiImplicitParam:它是对单个参数的说明
)
4.@ApiParam可以写在参数里面,对一个参数进行说明
5.@ApiModel: 它是对实体类的说明
6.@ApiModelProperty: 它是对实体类中属性的说明
4.springboot整合mybatis-plus
4.1 mp的简介
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
愿景
我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
-
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
-
损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
4.2 如何使用
(1)依赖
<dependencies>
<!--mp依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
(2)配置文件
(3) 表的实体类 Student
package com.zjl.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName(value = "tbl_student")
@ApiModel(value = "学生实体类")
public class Student implements Serializable {
@ApiModelProperty(value = "学生id")
private long id;
@ApiModelProperty(value = "学生姓名")
private String name;
@ApiModelProperty(value = "学生年龄")
private Integer age;
@ApiModelProperty(value = "学生性别")
private String sex;
@TableField(value = "c_id")
@ApiModelProperty(value = "班级id")
private Integer cid;
@ApiModelProperty(value = "学生生日")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
private Date birthday;
@ApiModelProperty(value = "学生头像")
private String headimg;
@TableField(exist = false)
@ApiModelProperty(value = "关联的班级对象")
private Clazz clazz;
private static final long serialVersionUID = 1L;
}
(4)表的Dao接口 UserDao
package com.zjl.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zjl.pojo.Student;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper生成代理实现类
*/
@Mapper
public interface StudentDao extends BaseMapper<Student> {
}
(5)单元测试
package com.zjl.springboot02;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zjl.dao.StudentDao;
import com.zjl.pojo.Student;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.List;
@ApiModel(value = "学生测试类")
@SpringBootTest
class Springboot02ApplicationTests {
@Autowired
private StudentDao studentDao;
@ApiModelProperty(value = "查询学生")
@Test
void testById() {
Student student = studentDao.selectById(1);
System.out.println(student);
}
@ApiModelProperty(value = "添加学生")
@Test
void testSave() {
Student student = new Student();
student.setName("二流");
student.setAge(18);
student.setCid(2);
student.setSex("男");
student.setHeadimg("ssss");
int insert = studentDao.insert(student);
System.out.println("影响行数:" + insert);
}
@ApiModelProperty(value = "删除学生")
@Test
void testDelete() {
// int delete = studentDao.deleteById(19);
// System.out.println("影响行数:"+delete);
//批量删除
// List<Integer> ids = Arrays.asList(1,2,3,4,5,6,7,8,9,20,21,22);
// int i = studentDao.deleteBatchIds(ids);
// System.out.println("影响行数:"+i);
//条件删除
UpdateWrapper<Student> wrapper = new UpdateWrapper<>();//修改的条件构造器
// wrapper.eq("name","董宇通");//name=董宇通
// wrapper.like("name","董");//模糊条件删除
wrapper.like("name", "董");//模糊条件删除
wrapper.or();//默认多个条件使用and连接。 如果想使用or 则调用or()
wrapper.ge("age", 18);//大于等于18的
// wrapper.lt("age",20);//小于等于20的
// wrapper.le("age",20);//小于等于20的
// wrapper.ne("age",20);//不等于等于20的
// wrapper.between("age",18,20);//年龄在18到20之间的
studentDao.delete(wrapper);//Wrapper对象:它是条件构造器
}
@ApiModelProperty(value = "修改学生")
@Test
void testUpdate() {
Student student = new Student();
studentDao.updateById(student);
}
}
注意:
如果实体类和表名不一致,以及属性名和列名不一致,主键属性和列名不一致
4.3 CRUD操作
(1)添加操作
@ApiModelProperty(value = "添加学生")
@Test
void testSave() {
Student student = new Student();
student.setName("二流");
student.setAge(18);
student.setCid(2);
student.setSex("男");
student.setHeadimg("ssss");
int insert = studentDao.insert(student);
System.out.println("影响行数:" + insert);
}
发现: mp会自动为主键生成值,默认按照雪花算法【得到的值100%不会重复】。能否修改主键的生成策略.---能---如果想使用主键自增必须要求数据库中表的主键是递增模式。
/**
* AUTO(0),递增 按照数据库表的主键递增模式
* NONE(1),人为输入id值
* INPUT(2),人为输入id值
* ASSIGN_ID(3),默认的算法。雪花算法
* ASSIGN_UUID(4),按照UUID生成---字符串
*/
(2)删除操作
@ApiModelProperty(value = "删除学生")
@Test
void testDelete() {
// int delete = studentDao.deleteById(19);
// System.out.println("影响行数:"+delete);
//批量删除
// List<Integer> ids = Arrays.asList(1,2,3,4,5,6,7,8,9,20,21,22);
// int i = studentDao.deleteBatchIds(ids);
// System.out.println("影响行数:"+i);
//条件删除
UpdateWrapper<Student> wrapper = new UpdateWrapper<>();//修改的条件构造器
// wrapper.eq("name","董宇通");//name=董宇通
// wrapper.like("name","董");//模糊条件删除
wrapper.like("name", "董");//模糊条件删除
wrapper.or();//默认多个条件使用and连接。 如果想使用or 则调用or()
wrapper.ge("age", 18);//大于等于18的
// wrapper.lt("age",20);//小于等于20的
// wrapper.le("age",20);//小于等于20的
// wrapper.ne("age",20);//不等于等于20的
// wrapper.between("age",18,20);//年龄在18到20之间的
studentDao.delete(wrapper);//Wrapper对象:它是条件构造器
}
(3)修改
/**
* 修改
* @throws ParseException
*/
@Test
void testUpdate() throws ParseException {
Student student = new Student();
student.setId(1);
student.setName("二流");
student.setAge(18);
student.setSex("男");
student.setCid(2);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date parse = format.parse("2000-10-20");
student.setBirthday(parse);
student.setHeadimg("ssss");
int update = studentDao.updateById(student);
System.out.println("影响行数:" + update);
}
(4)查询
@Test
void testSelect() {
//批量查询
// List<Integer> ids = Arrays.asList(1,2,3,4);
// List<Student> students = studentDao.selectBatchIds(ids);
// System.out.println(students);
//条件查询,
QueryWrapper<Student> wrapper = new QueryWrapper<Student>();//条件构造器
// wrapper.select("name", "age");//查询指定列
wrapper.orderByDesc("age");//倒序
// wrapper.orderByAsc("age");//升序
List<Student> students = studentDao.selectList(wrapper);//根据条件查询,如果传递的条件对象为null,则查询全部
System.out.println(students);
}