题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| create table t_requirement ( i_require_id BIGINT primary key auto_increment not null comment '需求标识', s_title VARCHAR(256) comment '需求标题', s_description VARCHAR(2048) comment '需求描述', s_comment VARCHAR(1024) comment '备注', i_source TINYINT comment '需求来源 枚举,1内部、2外部', s_require_aim_meaning VARCHAR(512) comment '业务目的及意义', s_require_background_current VARCHAR(512) comment '需求背景及现状', d_post_date DATETIME comment '提出时间', d_wish_date DATETIME comment '期望完成时间' ) comment '需求管理表'; alter table t_requirement add constraint PK_t_requient_i_requi_id426B primary key (i_require_id);
|
1 2 3 4 5 6 7 8 9
| 使用以上SQL语句,基于MySQL或其他数据库创建一个【需求管理表】。并基于该表实现基本的 新增 和 查询 业务接口,具体要求如下: 1、数据库连接方式不限,可通过JDBC或其他业务框架实现。 2、新增:做好接口请求参数的基本校验,包括:需求标题、需求来源为必填项,需求标题、需求描述分别不能超过20、50个字符。 3、查询:支持通过需求标题进行模糊查询。
验证: 1、 接口必填参数未赋值时,请求返回错误状态码400,成功则返回状态码200。 2、 新增的数据可通过查询接口进行筛选。 3、 通过浏览器http请求或postman等工具进行验证。
|
思路分析
- 整体框架使用String Boot 加 MyBatis Plus实现
- 这里需要对字符串进行长度校验,可以通过Hibernate Validator来实现,spring-boot-starter-web集成了这个工具
- 定义Result类,用来统一返回结果
- 使用全局异常处理类来处理异常
- 定义枚举类来实现source字段
创建项目,引入依赖,运行SQL,编写配置
由于idea版本过高,这里创建项目时只能使用JDK 17及以上版本,创建好项目后我会在pom文件中改为JDK 8
还需要而外引入的依赖有:MyBatis Plus、Lombok
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
|
运行SQL语句,创建对应的SQL表
创建application.yaml,写入相关配置
1 2 3 4 5 6 7 8 9 10 11 12 13
| server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 username: root password: "020427" mybatis-plus: mapper-locations: classpath:mapping/*.xml type-aliases-package: com.zheng.entity
|
创建枚举类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Getter public enum Source { INTERIOR(1,"内部"), EXTERNAL(2,"外部");
@EnumValue private int code; private String value; Source(Integer code, String value) { this.code = code; this.value = value; } }
|
- @EnumValue:哪个属性被标注,数据库就会保存哪个属性,由于数据库source的是tinyint类型的,这里标记code
创建实体类
hibernate validator提供了很多注解,让我们在创建实体类时,能够对其中的属性进行约束
| 注解 |
说明 |
| @NotNull |
被注释的元素(任何元素)必须不为null,但集合为空也是可以的。没啥实际意义 |
| @NotEmpty |
用来校验字符串、集合、map、数组不能为null或空 (字符串传入空格也不可以)(集合需至少包含一个元素)功能强于@NotNull |
| @NotBlank |
只用来校验字符串不为null,不为空值,不为全空格。功能强大于@NotEmpty |
| @Size(max=, min=) |
指定的字符串、集合、map、数组长度必须在指定的max和min范围内。(允许元素为null,字符串允许为空格) |
| @Length(min=,max=) |
只用来校验字符串,长度必须在指定的max和min范围内。(允许元素为null) |
| @Range(min=,max=) |
用来校验数字或字符串的大小必须在指定的min和max范围内,字符串会转成数字进行比较,如果不是数字校验不通过。(允许元素为null) |
| @Min() |
校验数字(包括integer、short、long、int等)的最小值,不支持小数即double和float。(允许元素为null) |
| @Max() |
校验数字(包括integer、short、long、int等)的最大值,不支持小数即double和float。(允许元素为null) |
| @Pattern() |
正则表达式匹配,可用来校验年月日格式是否包含特殊字符 |
| @Valid |
递归的对关联对象进行校验,如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.zheng.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.Date;
@TableName("t_requirement") @NoArgsConstructor @AllArgsConstructor @Data public class Requirement { @TableField("i_require_id") private Integer requireId; @TableField("s_title") @NotBlank(message = "标题不能为空") @Length(min = 1, max = 20, message = "需求标题不能超过20个字符") private String title; @Length(max = 50, message = "需求描述不能超过50个字符") @TableField("s_description") private String description; @TableField("s_comment") private String comment; @NotNull(message = "需求源不能为空") @TableField("i_source") private Source source; @TableField("s_require_aim_meaning") private String requireAmiMeaning; @TableField("s_require_background_current") private String requireBackgroundCurrent; @TableField("d_post_date") private Date postDate; @TableField("d_wish_date") private Date wishDate;
}
|
创建统一返回结果类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.zheng.util;
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
@Data @NoArgsConstructor @AllArgsConstructor public class Result { private Integer code; private String msg; private Object data;
public static Result Success() { return new Result(200, "success", null); }
public static Result Success(Object data) { return new Result(200, "success", data); }
public static Result Error(String msg) { return new Result(400, msg, null); } }
|
创建全局异常处理类
用来处理,必填字段非空,或者字段超出长度限制
1 2 3 4 5 6 7 8 9 10 11 12
| @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Result> handleValidationExceptions(MethodArgumentNotValidException ex) { String errorMessage = ex.getBindingResult().getFieldError().getDefaultMessage(); Result result = Result.Error(errorMessage); return new ResponseEntity<>(result, HttpStatus.BAD_REQUEST); } }
|
controller层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @RestController @RequestMapping("/requirement") public class RequirementController { private final RequirementService requirementService;
@Autowired public RequirementController(RequirementService requirementService) { this.requirementService = requirementService; }
@PostMapping private Result create(@Valid @RequestBody Requirement requirement) { return requirementService.create(requirement); }
@GetMapping() private Result get(@RequestParam(required = false) String title) { return requirementService.get(title); }
}
|
service层
1 2 3 4 5
| public interface RequirementService extends IService<Requirement> { Result create(Requirement requirement);
Result get(String title); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Service public class RequirementServiceImpl extends ServiceImpl<RequirementMapper, Requirement> implements RequirementService {
@Autowired private RequirementMapper requirementMapper;
@Override public Result create(Requirement requirement) { requirementMapper.insert(requirement); return Result.Success(); }
@Override public Result get(String title) { QueryWrapper<Requirement> wrapper = new QueryWrapper<>(); if (title != null) { wrapper.like("s_title", title); } List<Requirement> requirements = requirementMapper.selectList(wrapper); return Result.Success(requirements); } }
|
mapper层
1 2 3
| @Mapper public interface RequirementMapper extends BaseMapper<Requirement> { }
|
POM文件
编写代码的过程中可能又引入了一些依赖,这里给出所有依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.zheng</groupId> <artifactId>Interview</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Interview</name> <description>Interview</description> <properties> <java.version>8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.2.0.Final</version> </dependency>
</dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>
|
整体项目架构图
新增测试
没有输入标题,提示标题不能为空,符合要求

没有输入需求来源,提示需求源不能为空,符合要求

标题长度超过20个字符,输出需求标题不能超过20个字符,符合要求

需求描述超过50个字符,提示需求描述不能超过50个字符

输入符合要求的数据,返回200,保存成功

模糊查询测试
现在数据库中的数据

测试不输入title,也就是查询所有,总共6条数据,符合要求

根据Title模糊查询,添加Title,值为测试,共查询到两条数据,符合要求
