学习进度条

检测工单功能开发学习总结

一、学习进度

  • 今日所花时间:一小时
  • 今日代码量:100 行
  • 博客量:1 篇

二、了解到的知识点

1. 数据的分页查询

在本次检测工单功能开发中,数据的分页查询是核心功能之一。通过使用 PageBean 工具类来封装分页结果,包含总条数 total 和当前页数据集合 items,方便前端进行展示。

package com.example.littlebabydemo0425.pojo;

import java.util.List;

// 分页返回结果对象
public class PageBean<T> {
    private Long total; // 总条数
    private List<T> items; // 当前页数据集合

    public PageBean() {
    }

    public PageBean(Long total, List<T> items) {
        this.total = total;
        this.items = items;
    }

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
    }

    public List<T> getItems() {
        return items;
    }

    public void setItems(List<T> items) {
        this.items = items;
    }
}

DetectionOrderMapper 中,实现了分页查询的逻辑。通过计算偏移量 offset,结合 LIMIT 关键字进行分页查询,同时统计满足条件的总记录数。

// 分页查询检测工单
@Select("SELECT * FROM detection_order LIMIT #{offset}, #{pageSize}")
List<DetectionOrder> selectByPage(@Param("offset") Integer offset,
                                  @Param("pageSize") Integer pageSize);

// 统计检测工单数量
@Select("SELECT COUNT(*) FROM detection_order")
int count();

/**
 * 分页查询检测工单列表
 * @param pageNum 页码
 * @param pageSize 每页大小
 * @param deviceId 设备ID(可选)
 * @param orderCode 工单编号(可选)
 * @param status 工单状态(可选)
 * @return 分页结果
 */
default PageBean<DetectionOrder> getDetectionOrders(Integer pageNum, Integer pageSize,
                                                    Long deviceId, String orderCode, Integer status) {
    PageBean<DetectionOrder> pb = new PageBean<>();

    // 计算偏移量
    int offset = (pageNum - 1) * pageSize;

    // 查询数据
    List<DetectionOrder> detectionOrders = selectByCondition(deviceId, orderCode, status, offset, pageSize);
    pb.setItems(detectionOrders);

    // 查询总数
    long total = countByCondition(deviceId, orderCode, status);
    pb.setTotal(total);

    return pb;
}

2. Spring Boot 框架

  • 控制器(Controller):使用 @RestController 注解将 DetectionOrderController 标记为 RESTful 风格的控制器,处理前端的 HTTP 请求。通过 @RequestMapping 注解指定请求的 URL 路径,支持跨域请求(@CrossOrigin)。
@RestController
@RequestMapping("/api/detection-orders")
@CrossOrigin(origins = "http://localhost:5173") // 添加CORS支持
public class DetectionOrderController {

    @Autowired
    private DetectionOrderMapper detectionOrderMapper;

    // 分页查询检测工单列表
    @GetMapping
    public Result<PageBean<DetectionOrder>> getDetectionOrders(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) Long deviceId,
            @RequestParam(required = false) String orderCode,
            @RequestParam(required = false) Integer status) {
        try {
            PageBean<DetectionOrder> pageBean = detectionOrderMapper.getDetectionOrders(
                    pageNum, pageSize, deviceId, orderCode, status);
            return Result.success(pageBean);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("获取检测工单列表失败: " + e.getMessage());
        }
    }
    // 其他请求处理方法...
}
  • 服务层(Mapper):使用 MyBatis 的 @Mapper 注解将 DetectionOrderMapper 标记为映射器接口,通过注解方式编写 SQL 语句,实现对数据库的增删改查操作。同时,使用 @SelectProvider 注解动态生成 SQL 语句,支持条件查询。
@Mapper
public interface DetectionOrderMapper {

    // 新增检测工单
    @Insert("INSERT INTO detection_order(order_code, plan_id, device_id, assignee_id, " +
            "start_time, end_time, status, device_status, result_desc) " +
            "VALUES(#{orderCode}, #{planId}, #{deviceId}, #{assigneeId}, " +
            "#{startTime}, #{endTime}, #{status}, #{deviceStatus}, #{resultDesc})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(DetectionOrder detectionOrder);

    // 动态生成查询语句
    @SelectProvider(type = DetectionOrderSqlProvider.class, method = "selectByCondition")
    List<DetectionOrder> selectByCondition(
            @Param("deviceId") Long deviceId,
            @Param("orderCode") String orderCode,
            @Param("status") Integer status,
            @Param("offset") int offset,
            @Param("pageSize") int pageSize);

    // SQL提供类
    class DetectionOrderSqlProvider {
        public String selectByCondition(
                @Param("deviceId") Long deviceId,
                @Param("orderCode") String orderCode,
                @Param("status") Integer status,
                @Param("offset") int offset,
                @Param("pageSize") int pageSize) {
            return new SQL() {{
                SELECT("*");
                FROM("detection_order");
                if (deviceId != null) {
                    WHERE("device_id = #{deviceId}");
                }
                if (orderCode != null && !orderCode.isEmpty()) {
                    WHERE("order_code LIKE CONCAT('%', #{orderCode}, '%')");
                }
                if (status != null) {
                    WHERE("status = #{status}");
                }
                ORDER_BY("id DESC");
            }}.toString() + " LIMIT #{offset}, #{pageSize}";
        }
    }
}

3. 数据库操作

  • 实体类(Entity):使用 JPA 的注解将 DetectionOrder 类映射到数据库表 detection_order,通过 @Column 注解指定字段的属性,同时使用 @Index 注解创建索引,提高查询效率。
package com.example.littlebabydemo0425.pojo;

import jakarta.persistence.*;
import java.util.Date;

@Entity
@Table(name = "detection_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 DetectionOrder {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "order_code", length = 64, nullable = false)
    private String orderCode;

    // 其他字段...

    // Getters and Setters
}
  • 事务管理:在 DetectionOrderController 中,使用 @Transactional 注解对涉及数据库操作的方法进行事务管理,确保数据的一致性和完整性。
// 新增检测工单
@PostMapping
@Transactional
public Result<DetectionOrder> createDetectionOrder(@RequestBody DetectionOrder detectionOrder) {
    try {
        // 验证必要字段
        if (detectionOrder.getOrderCode() == null || detectionOrder.getDeviceId() == null) {
            return Result.error("工单编号和设备ID不能为空");
        }

        // 检查工单编号是否已存在
        DetectionOrder existingOrder = detectionOrderMapper.selectByOrderCode(detectionOrder.getOrderCode());
        if (existingOrder != null) {
            return Result.error("工单编号已存在");
        }

        // 设置初始状态和创建时间
        if (detectionOrder.getStatus() == null) {
            detectionOrder.setStatus(0); // 默认状态为待处理
        }
        detectionOrder.setCreateTime(new Date());
        detectionOrder.setUpdateTime(new Date());

        // 调用mapper层的插入方法
        int rowsInserted = detectionOrderMapper.insert(detectionOrder);
        if (rowsInserted > 0) {
            return Result.success(detectionOrder);
        } else {
            return Result.error("添加检测工单失败");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return Result.error("添加检测工单时发生异常: " + e.getMessage());
    }
}

三、总结

通过本次检测工单功能的开发,我深入学习了 Spring Boot 框架的使用,掌握了数据的分页查询、动态 SQL 生成、事务管理等技术。同时,对数据库操作和实体类的映射有了更深入的理解。在后续的开发中,我将继续巩固这些知识,提高自己的编程能力。

posted @ 2025-05-14 21:24  haoyinuo  阅读(21)  评论(0)    收藏  举报