order (vo,xml)

本文介绍了一个订单系统的数据库设计及对应的Java实体类定义。详细解释了订单表的字段含义,并展示了如何通过Java类映射到数据库表,包括订单状态、时间、用户关联等属性。
package cn.itcast.shop.order.vo;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import cn.itcast.shop.user.vo.User;

/*CREATE TABLE `orders` (
`oid` int(11) NOT NULL AUTO_INCREMENT,
`total` double DEFAULT NULL,
`ordertime` datetime DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`name` varchar(21) DEFAULT NULL,
`addr` varchar(60) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
`uid` int(11) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `FKC3DF62E5AA3D9C7` (`uid`),
CONSTRAINT `FKC3DF62E5AA3D9C7` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
*/
public class Order {
    private Integer oid;
    private Double total;
    private Date ordertime;
    private Integer state;// 1:未付款   2:订单已经付款   3:已经发货   4:订单结束
    private String name;
    private String phone;
    private String addr;
    //订单的外键
    private User user;
    // 配置订单项的集合
    private Set<OrderItem> orderItems=new HashSet<OrderItem>();
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
    public Double getTotal() {
        return total;
    }
    public void setTotal(Double total) {
        this.total = total;
    }
    public Date getOrdertime() {
        return ordertime;
    }
    public void setOrdertime(Date ordertime) {
        this.ordertime = ordertime;
    }
    public Integer getState() {
        return state;
    }
    public void setState(Integer state) {
        this.state = state;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getAddr() {
        return addr;
    }
    public void setAddr(String addr) {
        this.addr = addr;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public Set<OrderItem> getOrderItems() {
        return orderItems;
    }
    public void setOrderItems(Set<OrderItem> orderItems) {
        this.orderItems = orderItems;
    }
    
    
}


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="cn.itcast.shop.order.vo.Order" table="orders">
            <id name="oid">
                    <generator class="native"></generator>
            </id>
            <property name="total"></property>
            <property name="ordertime"></property>
            <property name="state"></property>
            <property name="name"></property>
            <property name="phone"></property>
            <property name="addr"></property>
            
            <many-to-one name="user" class="cn.itcast.shop.user.vo.User" column="uid"></many-to-one>
        <!--  to     (表示对象)对, 对于, 对…来说 -->
        <!--订单说:篮子有很多个 一个篮子不可能被多个消费者争抢 -->
            <set name="orderItems">
                <key column="oid"></key>
                <one-to-many class="cn.itcast.shop.order.vo.OrderItem" />
                <!-- 订单说: 我这个篮子放了很多种商品 -->
            </set>
        </class>
    </hibernate-mapping>

public Result savePlanCopyRepairOrder(@Valid @RequestBody PlanRepairOrderCopyVO vo) { try { // 1. 查询原始工单(假设 vo.id 是原始工单ID) PlanRepairOrderDTO original = planRepairOrderMapper.selectById(vo.getId()); if (original == null) { return Result.fail("原始工单不存在"); } // 2. 创建新工单并复制属性 PlanRepairOrderDTO newOrder = new PlanRepairOrderDTO(); BeanUtils.copyProperties(newOrder, original); // 浅拷贝,注意复杂对象需深拷贝 // 3. 设置新工单属性 newOrder.setId(null); // 清空主键,表示插入新记录 newOrder.setName(vo.getName()); // 设置新名称 // 时间字段转换 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); try { LocalDateTime start = LocalDateTime.parse(vo.getPlanStartTime(), formatter); LocalDateTime end = LocalDateTime.parse(vo.getPlanEndTime(), formatter); // 如果 DTO 使用的是 Date 类型,可以转换为 Date newOrder.setPlanStartTime(Date.from(start.atZone(ZoneId.systemDefault()).toInstant())); newOrder.setPlanEndTime(Date.from(end.atZone(ZoneId.systemDefault()).toInstant())); } catch (DateTimeParseException e) { return Result.fail("时间格式错误,请使用 yyyy-MM-dd HH:mm:ss"); } newOrder.setAreaId(vo.getAreaId()); // 设置区域ID newOrder.setLineId(vo.getLineId()); // 设置线路ID newOrder.setStationId(vo.getStationId()); // 设置站点ID newOrder.setMaintenanceContent(vo.getMaintenanceContent()); // 设置检修内容 newOrder.setResponsiblePersonId(vo.getResponsiblePersonId()); // 设置责任人ID newOrder.setExecutors(convertExecutorsToJson(vo.getExecutors())); // 设置执行人JSON字符串 newOrder.setEquipmentType(vo.getEquipmentType()); // 设置设备类型 newOrder.setPeriodType(vo.getPeriodType()); // 设置周期类型 // 4. 生成新的工单单号:WOS + partnerId + 年月日 + 5位流水号 String newId = generateWorkOrderId(original.getPartnerId()); newOrder.setId(newId); // 5. 插入新工单 planRepairOrderMapper.insert(newOrder); // 6. 返回成功结果 return Result.success("拷贝成功", newOrder.getId()); } catch (Exception e) { // 异常自动回滚 return Result.fail("拷贝工单失败: " + e.getMessage()); } } /** * 生成新的工单单号 * 格式:WOS + partnerId + 年月日 + 5位流水号 */ private String generateWorkOrderId(Integer partnerId) { String prefix = "WOS"; String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); String seq = dailySequenceGenerator.getNextSequence(); // 获取5位流水号 return prefix + partnerId + dateStr + seq; } /** * 将执行人列表转换为 JSON 字符串存储 */ private String convertExecutorsToJson(List<Integer> executorIds) { return new Gson().toJson(executorIds); } 优化以上代码,报错public Result savePlanCopyRepairOrder(@Valid @RequestBody PlanRepairOrderCopyVO vo) { try { // 1. 查询原始工单(假设 vo.id 是原始工单ID) PlanRepairOrderDTO original = planRepairOrderMapper.selectById(vo.getId()); if (original == null) { return Result.fail("原始工单不存在"); } // 2. 创建新工单并复制属性 PlanRepairOrderDTO newOrder = new PlanRepairOrderDTO(); BeanUtils.copyProperties(newOrder, original); // 浅拷贝,注意复杂对象需深拷贝 // 3. 设置新工单属性 newOrder.setId(null); // 清空主键,表示插入新记录 newOrder.setName(vo.getName()); // 设置新名称 // 时间字段转换 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); try { LocalDateTime start = LocalDateTime.parse(vo.getPlanStartTime(), formatter); LocalDateTime end = LocalDateTime.parse(vo.getPlanEndTime(), formatter); // 如果 DTO 使用的是 Date 类型,可以转换为 Date newOrder.setPlanStartTime(Date.from(start.atZone(ZoneId.systemDefault()).toInstant())); newOrder.setPlanEndTime(Date.from(end.atZone(ZoneId.systemDefault()).toInstant())); } catch (DateTimeParseException e) { return Result.fail("时间格式错误,请使用 yyyy-MM-dd HH:mm:ss"); } newOrder.setAreaId(vo.getAreaId()); // 设置区域ID newOrder.setLineId(vo.getLineId()); // 设置线路ID newOrder.setStationId(vo.getStationId()); // 设置站点ID newOrder.setMaintenanceContent(vo.getMaintenanceContent()); // 设置检修内容 newOrder.setResponsiblePersonId(vo.getResponsiblePersonId()); // 设置责任人ID newOrder.setExecutors(convertExecutorsToJson(vo.getExecutors())); // 设置执行人JSON字符串 newOrder.setEquipmentType(vo.getEquipmentType()); // 设置设备类型 newOrder.setPeriodType(vo.getPeriodType()); // 设置周期类型 // 4. 生成新的工单单号:WOS + partnerId + 年月日 + 5位流水号 String newId = generateWorkOrderId(original.getPartnerId()); newOrder.setId(newId); // 5. 插入新工单 planRepairOrderMapper.insert(newOrder); // 6. 返回成功结果 return Result.success("拷贝成功", newOrder.getId()); } catch (Exception e) { // 异常自动回滚 return Result.fail("拷贝工单失败: " + e.getMessage()); } } /** * 生成新的工单单号 * 格式:WOS + partnerId + 年月日 + 5位流水号 */ private String generateWorkOrderId(Integer partnerId) { String prefix = "WOS"; String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); String seq = dailySequenceGenerator.getNextSequence(); // 获取5位流水号 return prefix + partnerId + dateStr + seq; } /** * 将执行人列表转换为 JSON 字符串存储 */ private String convertExecutorsToJson(List<Integer> executorIds) { return new Gson().toJson(executorIds); }Cannot resolve symbol 'SimpleDateFormat'、Cannot resolve symbol 'dailySequenceGenerator'和Cannot resolve symbol 'Gson',优化后的代码是什么 、
08-03
你提到“没有xml”,说明你当前使用的是 **纯 Java 注解方式** 或 **Java 配置类** 来定义 MyBatis 的 SQL,而不是传统的 XML 映射文件(如 `XXXMapper.xml`)。因此,我们应将原本在 XML 中编写的复杂 SQL 改为使用注解(如 `@Select`)写在 Mapper 接口里。 但由于你的 SQL 包含 **CTE(Common Table Expression)递归查询**,且较长,**MyBatis 的 `@Select` 注解对多行字符串支持不友好**,所以我们需要: 1. 使用 **注解 + 转义换行符** 2. 或者更推荐:使用 **SQL Provider(@SelectProvider)机制** --- ## ✅ 正确做法:使用 `@SelectProvider` 实现复杂动态 SQL(无 XML) ### 1. 创建 SQL 提供类 ```java // com/example/system/mapper/BatchSqlProvider.java package com.example.system.mapper; public class BedOccupancySqlProvider { public String countMonthlyStats() { return """ WITH RECURSIVE calendar AS ( SELECT #{startDate} AS date UNION ALL SELECT DATE_ADD(date, INTERVAL 1 DAY) FROM calendar WHERE date < CURRENT_DATE() ), daily_occupancy AS ( SELECT c.date, COUNT(r.id) AS occupied_bed_count FROM calendar c LEFT JOIN bed_occupancy_records r ON c.date >= DATE(r.check_in_time) AND (r.check_out_time IS NULL OR c.date < DATE(r.check_out_time)) GROUP BY c.date ) SELECT MONTH(d.date) AS month, AVG(d.occupied_bed_count) AS used, (SELECT COUNT(*) FROM beds) - AVG(d.occupied_bed_count) AS free FROM daily_occupancy d WHERE d.date >= #{startDate} GROUP BY MONTH(d.date) ORDER BY month """; } } ``` > ⚠️ 注意: > - Java 15+ 才支持三重引号 `"""..."""` > - 如果是低版本 Java,请用 `+` 拼接字符串,并注意空格 #### 兼容低版本 Java 写法(Java 8): ```java public String countMonthlyStats() { return "WITH RECURSIVE calendar AS ( " + "SELECT #{startDate} AS date " + "UNION ALL " + "SELECT DATE_ADD(date, INTERVAL 1 DAY) " + "FROM calendar " + "WHERE date < CURRENT_DATE() " + "), " + "daily_occupancy AS ( " + "SELECT " + " c.date, " + " COUNT(r.id) AS occupied_bed_count " + "FROM calendar c " + "LEFT JOIN bed_occupancy_records r " + " ON c.date >= DATE(r.check_in_time) " + " AND (r.check_out_time IS NULL OR c.date < DATE(r.check_out_time)) " + "GROUP BY c.date " + ") " + "SELECT " + " MONTH(d.date) AS month, " + " AVG(d.occupied_bed_count) AS used, " + " (SELECT COUNT(*) FROM beds) - AVG(d.occupied_bed_count) AS free " + "FROM daily_occupancy d " + "WHERE d.date >= #{startDate} " + "GROUP BY MONTH(d.date) " + "ORDER BY month"; } ``` --- ### 2. 修改 Mapper 接口,使用 `@SelectProvider` ```java // BedOccupancyRecordMapper.java package com.example.system.mapper; import com.example.system.domain.vo.BedStatsVO; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.SelectProvider; import java.time.LocalDate; import java.util.List; public interface BedOccupancyRecordMapper { @SelectProvider(type = BedOccupancySqlProvider.class, method = "countMonthlyStats") List<BedStatsVO> countMonthlyStats(@Param("startDate") LocalDate startDate); } ``` --- ### 3. 定义 VO 类接收结果 ```java // BedStatsVO.java package com.example.system.domain.vo; public class BedStatsVO { private Integer month; private Double used; // 平均每日使用床位数 private Double free; // 平均每天空闲床位数 // Getters and Setters public Integer getMonth() { return month; } public void setMonth(Integer month) { this.month = month; } public Double getUsed() { return Math.round(used * 100.0) / 100.0; } public void setUsed(Double used) { this.used = used; } public Double getFree() { return Math.max(0, Math.round(free * 100.0) / 100.0); } public void setFree(Double free) { this.free = free; } } ``` --- ### 4. Service 层调用示例 ```java // BedOccupancyRecordService.java @Service public class BedOccupancyRecordService { @Autowired private BedOccupancyRecordMapper bedOccupancyRecordMapper; public List<BedStatsVO> getMonthlyStats(LocalDate startDate) { return bedOccupancyRecordMapper.countMonthlyStats(startDate); } } ``` --- ### 5. 控制器返回给前端 ```java // BedController.java @RestController @RequestMapping("/system/bed") public class BedController { @Autowired private BedOccupancyRecordService bedOccupancyRecordService; @GetMapping("/stats") public AjaxResult getBedStats() { LocalDate sixMonthsAgo = LocalDate.now().minusMonths(6).withDayOfMonth(1); List<BedStatsVO> data = bedOccupancyRecordService.getMonthlyStats(sixMonthsAgo); return AjaxResult.success(data); } } ``` --- ## ✅ 前端适配建议(Vue) 确保前端处理浮点数并四舍五入为整数: ```js updateChart(apiData) { const totalBeds = 30; // 可从接口获取或静态配置 const usedData = Array(12).fill(0); const freeData = Array(12).fill(0); apiData.forEach(item => { const idx = item.month - 1; if (idx >= 0 && idx < 12) { usedData[idx] = Math.round(item.used); // 四舍五入 freeData[idx] = Math.max(0, Math.round(item.free)); } }); // ... 设置 ECharts option } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值