学习进度条
开发时间:1小时
代码量:约100行
博客:1篇
了解知识点:
核心代码实现
1. 实体类 MaintenanceOrder
package com.example.littlebabydemo0425.pojo;
import jakarta.persistence.*;
import java.util.Date;
@Entity
@Table(name = "maintenance_order", indexes = {
@Index(name = "idx_plan_id", columnList = "plan_id"),
@Index(name = "idx_device_id", columnList = "device_id"),
@Index(name = "idx_status", columnList = "status")
})
public class MaintenanceOrder {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "order_code", length = 64, nullable = false)
private String orderCode;
@Column(name = "plan_id")
private String planId;
@Column(name = "device_id", nullable = false)
private Long deviceId;
@Column(name = "assignee_id")
private Long assigneeId;
@Column(name = "start_time")
private Date startTime;
@Column(name = "end_time")
private Date endTime;
@Column(name = "status", columnDefinition = "tinyint default 0")
private Integer status;
@Column(name = "maintenance_status", length = 16)
private String maintenanceStatus;
@Column(name = "result_desc", columnDefinition = "text")
private String resultDesc;
@Column(name = "create_time", columnDefinition = "datetime default CURRENT_TIMESTAMP")
private Date createTime;
@Column(name = "update_time", columnDefinition = "datetime default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP")
private Date updateTime;
// 省略getter和setter方法
}
技术要点:
- 使用了 JPA 注解定义实体类与数据库表的映射关系
- 通过
@Table注解定义了表名和索引 - 使用
@Column注解定义列属性,包括长度限制、非空约束等 - 自动生成时间戳:
create_time和update_time
2. Mapper 接口 MaintenanceOrderMapper
package com.example.littlebabydemo0425.mapper;
import com.example.littlebabydemo0425.pojo.MaintenanceOrder;
import com.example.littlebabydemo0425.pojo.PageBean;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;
import java.util.Date;
import java.util.List;
@Mapper
public interface MaintenanceOrderMapper {
// 基本CRUD操作
@Insert("INSERT INTO maintenance_order (order_code, plan_id, device_id, assignee_id, " +
"start_time, end_time, status, maintenance_status, result_desc) " +
"VALUES (#{orderCode}, #{planId}, #{deviceId}, #{assigneeId}, " +
"#{startTime}, #{endTime}, #{status}, #{maintenanceStatus}, #{resultDesc})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(MaintenanceOrder maintenanceOrder);
@Delete("DELETE FROM maintenance_order WHERE id = #{id}")
int deleteById(Long id);
@Update("UPDATE maintenance_order SET " +
"order_code = #{orderCode}, " +
"plan_id = #{planId}, " +
"device_id = #{deviceId}, " +
"assignee_id = #{assigneeId}, " +
"start_time = #{startTime}, " +
"end_time = #{endTime}, " +
"status = #{status}, " +
"maintenance_status = #{maintenanceStatus}, " +
"result_desc = #{resultDesc} " +
"WHERE id = #{id}")
int update(MaintenanceOrder maintenanceOrder);
// 查询方法
@Select("SELECT * FROM maintenance_order WHERE id = #{id}")
MaintenanceOrder selectById(Long id);
@Select("SELECT * FROM maintenance_order WHERE order_code = #{orderCode}")
MaintenanceOrder selectByOrderCode(String orderCode);
// 动态SQL查询
@SelectProvider(type = MaintenanceOrderSqlProvider.class, method = "selectByCondition")
List<MaintenanceOrder> selectByCondition(
@Param("orderCode") String orderCode,
@Param("planId") Long planId,
@Param("deviceId") Long deviceId,
@Param("assigneeId") Long assigneeId,
@Param("status") Integer status,
@Param("maintenanceStatus") String maintenanceStatus,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime,
@Param("offset") int offset,
@Param("pageSize") int pageSize);
// 分页查询默认实现
default PageBean<MaintenanceOrder> list(
Integer pageNum, Integer pageSize,
String orderCode, Long planId,
Long deviceId, Long assigneeId,
Integer status, String maintenanceStatus,
Date startTime, Date endTime) {
// 实现代码...
}
// SQL提供类
class MaintenanceOrderSqlProvider {
// 动态SQL生成方法
public String selectByCondition(...) {
// 实现代码...
}
public String countByCondition(...) {
// 实现代码...
}
}
}
技术要点:
- 使用 MyBatis 注解方式实现简单的 SQL 映射
- 通过
@SelectProvider实现动态 SQL 查询 - 使用 MyBatis 的 SQL 构建器类生成动态 SQL
- 默认方法实现分页查询逻辑
- 参数绑定和结果集映射
3. 控制器 MaintenanceOrderController
package com.example.littlebabydemo0425.controller;
import com.example.littlebabydemo0425.mapper.MaintenanceOrderMapper;
import com.example.littlebabydemo0425.pojo.MaintenanceOrder;
import com.example.littlebabydemo0425.pojo.PageBean;
import com.example.littlebabydemo0425.pojo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/api/maintenance/orders")
@CrossOrigin(origins = "http://localhost:5174")
public class MaintenanceOrderController {
@Autowired
private MaintenanceOrderMapper maintenanceOrderMapper;
// 分页查询
@GetMapping
public Result<PageBean<MaintenanceOrder>> list(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String orderCode,
@RequestParam(required = false) Long planId,
@RequestParam(required = false) Long deviceId,
@RequestParam(required = false) Long assigneeId,
@RequestParam(required = false) Integer status,
@RequestParam(required = false) String maintenanceStatus,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime) {
// 实现代码...
}
// 添加工单
@PostMapping
public Result<String> add(@RequestBody MaintenanceOrder maintenanceOrder) {
// 实现代码...
}
// 更新工单
@PutMapping("/{id}")
public Result<String> update(@PathVariable Long id, @RequestBody MaintenanceOrder maintenanceOrder) {
// 实现代码...
}
// 删除工单
@DeleteMapping("/{id}")
public Result<String> delete(@PathVariable Long id) {
// 实现代码...
}
// 根据ID查询
@GetMapping("/{id}")
public Result<MaintenanceOrder> getById(@PathVariable Long id) {
// 实现代码...
}
// 根据工单号查询
@GetMapping("/code/{orderCode}")
public Result<MaintenanceOrder> getByOrderCode(@PathVariable String orderCode) {
// 实现代码...
}
// 更新状态
@PatchMapping("/{id}/status")
public Result<String> updateStatus(
@PathVariable Long id,
@RequestParam Integer status) {
// 实现代码...
}
// 更新保养状态
@PatchMapping("/{id}/maintenance-status")
public Result<String> updateMaintenanceStatus(
@PathVariable Long id,
@RequestParam String maintenanceStatus) {
// 实现代码...
}
// 时间范围查询
@GetMapping("/time-range")
public Result<List<MaintenanceOrder>> getByTimeRange(
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date start,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date end) {
// 实现代码...
}
}
技术要点:
- RESTful API 设计规范
- Spring MVC 注解的使用 (
@RestController,@RequestMapping,@GetMapping等) - 请求参数处理 (
@RequestParam,@PathVariable,@RequestBody) - 日期格式处理 (
@DateTimeFormat) - 跨域处理 (
@CrossOrigin) - 统一响应格式 (
Result类)
学到的关键技术
1. Spring Boot 自动配置
通过 Spring Boot 的自动配置特性,快速搭建了项目框架,减少了大量样板代码的编写。
2. MyBatis 动态 SQL
- 使用
@SelectProvider注解实现复杂条件查询 - 通过 SQL 构建器类动态生成 SQL 语句
- 实现了灵活的分页查询功能
3. RESTful API 设计
- 合理使用 HTTP 方法 (GET/POST/PUT/DELETE/PATCH)
- 资源命名规范 (
/api/maintenance/orders) - 状态码和统一响应格式
4. 数据库设计优化
- 添加了适当的索引提高查询性能
- 使用自动生成的时间戳字段
- 合理的字段类型和约束
5. 异常处理
- 统一的错误返回格式
- 适当的错误信息提示
- 操作结果的明确反馈
开发心得
通过这个模块的开发,我深刻理解了 Spring Boot 和 MyBatis 的配合使用方式,掌握了 RESTful API 的设计原则,并学会了如何实现复杂的分页查询功能。特别是动态 SQL 的使用,让我能够灵活应对各种查询需求。
在开发过程中,我也遇到了一些挑战,比如日期参数的格式化处理、动态 SQL 的构建等,但通过查阅文档和不断尝试,最终都得到了解决。这些经验对我后续的开发工作非常有帮助。
这个项目让我对后端开发有了更深的理解,特别是在 API 设计和数据库操作方面积累了宝贵经验。未来我还计划加入更多的功能,如工单统计、导出功能等,进一步完善这个系统。

浙公网安备 33010602011771号