<think>我们使用若依框架(前后端分离版)的Oracle版本,基于Spring Boot、MyBatis。
根据需求,我们需要实现三个接口:
1. 根据领用单号(noc1523)查询主表数据(对应SQL1)
2. 根据资材品名(cdc0270)和仓库代码(cdc1386)查询表格数据(对应SQL2,当CDC5559=1时)
3. 根据资材品名(cdc0270)查询表格数据(对应SQL3,当CDC5559=2时)
步骤:
1. Domain层:创建实体类对应查询结果。
2. Mapper层:编写MyBatis接口及映射文件(或注解方式)定义SQL查询。
3. Service层:实现业务逻辑,调用Mapper层方法。
4. Controller层:提供API接口,调用Service层方法。
注意:由于SQL1和SQL2、SQL3查询的字段不同,需要两个不同的实体类。
首先,我们创建两个实体类:
1. 主表实体类(Dmth004MainData)对应SQL1查询结果:
- NOC1523, CDC0270, CDC1414, CDC5559, SUN8523, CDC1386
2. 表格数据实体类(WmssZclyTableData)对应SQL2和SQL3的查询结果(注意两个SQL返回的字段名需要一致,因为前端映射的字段相同):
- CD05185(对应资材品名,但SQL3中可能没有这个字段,需要调整SQL3使其与SQL2返回的字段名一致?)
实际上,根据需求,我们需要在表格中显示以下字段(与SQL2返回的字段对应):
tbNO00027B -> NO00027B (资材批量号)
tbSU00355 -> SU00355 (在库数量)
tbSUN8529 -> 实际数量(这个字段在查询结果中可能没有,需要前端处理,所以后端只需返回已有的字段)
tbSUN8530 -> 剩余数量(同样,这个字段在查询结果中没有,需要前端计算,所以后端只需返回在库数量,然后前端用SU00355作为初始剩余数量)
tbDRNK -> DRNK (领用顺序)
但是,注意SQL2和SQL3返回的字段:
SQL2返回:CD05185, CD00059, NO00027B, SU00355, HI05662, DRNK
SQL3返回:CD05185, CD00059, NO00027B, SU00355, HI05662, DRNK
因此,我们可以用同一个实体类来接收。
然而,我们注意到SQL1中查询的字段是:NOC1523, CDC0270, CDC1414, CDC5559, SUN8523, CDC1386
而SQL2和SQL3返回的字段是:CD05185, CD00059, NO00027B, SU00355, HI05662, DRNK
所以,我们需要两个实体类。
具体实现:
第一步:创建实体类
1. Dmth004MainData.java(对应表DMTH004,用于SQL1查询)
2. WmssZclyTableData.java(用于SQL2和SQL3查询)
第二步:Mapper接口
1. Dmth004MainDataMapper.java:定义根据领用单号查询的方法
2. WmssZclyMapper.java:定义两个方法,分别对应SQL2和SQL3
第三步:Service层
1. IZclyService.java:接口,声明业务方法
2. ZclyServiceImpl.java:实现类
第四步:Controller层:ZclyController.java
由于项目使用若依框架,我们按照其规范编写。
下面我们开始编写代码:
注意:SQL语句中使用了Oracle的语法和函数(如TRUNC, SYSDATE, DECODE, DENSE_RANK等),在MyBatis中直接写SQL字符串即可。
由于SQL2和SQL3比较复杂,特别是SQL2,我们将其写在XML映射文件中,也可以使用注解方式(但复杂SQL建议用XML)。
我们这里使用XML方式。
开始编写:
1. Domain实体类</think>下面是根据需求实现的后端代码(基于若依框架的Spring Boot + MyBatis结构):
### 1. Domain 实体类
```java
// 主表实体 Dmth004MainData.java
package com.ruoyi.project.wmss.domain;
public class Dmth004MainData {
private String noc1523; // 领用单号
private String cdc0270; // 资材品名
private String cdc1414; // 领用原价
private String cdc5559; // 类型标识
private String sun8523; // 要求领用数
private String cdc1386; // 仓库代码
// getters and setters
public String getNoc1523() { return noc1523; }
public void setNoc1523(String noc1523) { this.noc1523 = noc1523; }
public String getCdc0270() { return cdc0270; }
public void setCdc0270(String cdc0270) { this.cdc0270 = cdc0270; }
public String getCdc1414() { return cdc1414; }
public void setCdc1414(String cdc1414) { this.cdc1414 = cdc1414; }
public String getCdc5559() { return cdc5559; }
public void setCdc5559(String cdc5559) { this.cdc5559 = cdc5559; }
public String getSun8523() { return sun8523; }
public void setSun8523(String sun8523) { this.sun8523 = sun8523; }
public String getCdc1386() { return cdc1386; }
public void setCdc1386(String cdc1386) { this.cdc1386 = cdc1386; }
}
// 表格数据实体 WmssZclyTableData.java
package com.ruoyi.project.wmss.domain;
public class WmssZclyTableData {
private String tbNO00027B; // 资材批量号
private String tbSU00355; // 在库数量
private String tbSUN8529; // 实际数量
private String tbSUN8530; // 剩余数量
private String tbDRNK; // 领用顺序
// getters and setters
public String getTbNO00027B() { return tbNO00027B; }
public void setTbNO00027B(String tbNO00027B) { this.tbNO00027B = tbNO00027B; }
public String getTbSU00355() { return tbSU00355; }
public void setTbSU00355(String tbSU00355) { this.tbSU00355 = tbSU00355; }
public String getTbSUN8529() { return tbSUN8529; }
public void setTbSUN8529(String tbSUN8529) { this.tbSUN8529 = tbSUN8529; }
public String getTbSUN8530() { return tbSUN8530; }
public void setTbSUN8530(String tbSUN8530) { this.tbSUN8530 = tbSUN8530; }
public String getTbDRNK() { return tbDRNK; }
public void setTbDRNK(String tbDRNK) { this.tbDRNK = tbDRNK; }
}
```
### 2. Mapper 接口及 XML
```java
// Dmth004MainDataMapper.java
package com.ruoyi.project.wmss.mapper;
import com.ruoyi.project.wmss.domain.Dmth004MainData;
import org.apache.ibatis.annotations.Param;
public interface Dmth004MainDataMapper {
Dmth004MainData selectByNoc1523(@Param("noc1523") String noc1523);
}
```
```xml
<!-- resources/mapper/wmss/Dmth004MainDataMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.project.wmss.mapper.Dmth004MainDataMapper">
<select id="selectByNoc1523" resultType="Dmth004MainData">
SELECT
NOC1523,
CDC0270,
CDC1414,
CDC5559,
SUN8523,
CDC1386
FROM
DMTH004
WHERE
NOC1523 = #{noc1523}
</select>
</mapper>
```
```java
// WmssZclyMapper.java
package com.ruoyi.project.wmss.mapper;
import com.ruoyi.project.wmss.domain.WmssZclyTableData;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface WmssZclyMapper {
List<WmssZclyTableData> selectTableDataBySql2(
@Param("cdc0270") String cdc0270,
@Param("cdc1386") String cdc1386
);
List<WmssZclyTableData> selectTableDataBySql3(
@Param("cdc0270") String cdc0270
);
}
```
```xml
<!-- resources/mapper/wmss/WmssZclyMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.project.wmss.mapper.WmssZclyMapper">
<!-- SQL2 查询 -->
<select id="selectTableDataBySql2" resultType="WmssZclyTableData">
SELECT
NO00027B AS tbNO00027B,
SU00355 AS tbSU00355,
'' AS tbSUN8529, <!-- 实际数量初始为空 -->
SU00355 AS tbSUN8530, <!-- 剩余数量初始等于在库数量 -->
DRNK AS tbDRNK
FROM (
SELECT CD05185, CD00059, NO00027B, SU00355, HI05662, DENSE_RANK() OVER(PARTITION BY CD05185 ORDER BY HI05662) DRNK
FROM (
SELECT
T1.CD05185,
T1.CD00059,
T1.NO00027B,
T1.SU00355,
T1.HI05662,
T1.SU00355 - DECODE(T2.SUN6470_1, NULL, 0, T2.SUN6470_1) JIANSHU
FROM (
SELECT
CD05185, CD00059, NO00027B, SU00355, HI05662
FROM SCHM_C600_WME.MV0009G@SPIRITS
WHERE
CD05185 = #{cdc0270}
AND CD00059 = #{cdc1386}
AND KB00032 <> 'S'
AND SU00355 <> 0
AND HI05662 > TRUNC(SYSDATE) + 1
ORDER BY HI05662, NO00027B
) T1
LEFT JOIN (
SELECT
NOC0203,
DECODE(SUM(SUN6470), NULL, 0, SUM(SUN6470)) SUN6470_1
FROM DMTH006
WHERE
CDC0270 = #{cdc0270}
AND CDC1386 = #{cdc1386}
AND KBC0001 = '0'
GROUP BY NOC0203
) T2 ON T1.NO00027B = T2.NOC0203
)
WHERE JIANSHU > 0
)
ORDER BY DRNK, HI05662
</select>
<!-- SQL3 查询 -->
<select id="selectTableDataBySql3" resultType="WmssZclyTableData">
SELECT
NO00027B AS tbNO00027B,
SU00355 AS tbSU00355,
'' AS tbSUN8529, <!-- 实际数量初始为空 -->
SU00355 AS tbSUN8530, <!-- 剩余数量初始等于在库数量 -->
DRNK AS tbDRNK
FROM
DMTH002
WHERE
CDC0270 = #{cdc0270}
</select>
</mapper>
```
### 3. Service 服务层
```java
// IZclyService.java
package com.ruoyi.project.wmss.service;
import com.ruoyi.project.wmss.domain.Dmth004MainData;
import com.ruoyi.project.wmss.domain.WmssZclyTableData;
import java.util.List;
public interface IZclyService {
Dmth004MainData getMainData(String noc1523);
List<WmssZclyTableData> getTableDataBySQL2(String cdc0270, String cdc1386);
List<WmssZclyTableData> getTableDataBySQL3(String cdc0270);
}
```
```java
// ZclyServiceImpl.java
package com.ruoyi.project.wmss.service.impl;
import com.ruoyi.project.wmss.domain.Dmth004MainData;
import com.ruoyi.project.wmss.domain.WmssZclyTableData;
import com.ruoyi.project.wmss.mapper.Dmth004MainDataMapper;
import com.ruoyi.project.wmss.mapper.WmssZclyMapper;
import com.ruoyi.project.wmss.service.IZclyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ZclyServiceImpl implements IZclyService {
@Autowired
private Dmth004MainDataMapper dmth004Mapper;
@Autowired
private WmssZclyMapper wmssZclyMapper;
@Override
public Dmth004MainData getMainData(String noc1523) {
return dmth004Mapper.selectByNoc1523(noc1523);
}
@Override
public List<WmssZclyTableData> getTableDataBySQL2(String cdc0270, String cdc1386) {
return wmssZclyMapper.selectTableDataBySql2(cdc0270, cdc1386);
}
@Override
public List<WmssZclyTableData> getTableDataBySQL3(String cdc0270) {
return wmssZclyMapper.selectTableDataBySql3(cdc0270);
}
}
```
### 4. Controller 控制层
```java
// ZclyController.java
package com.ruoyi.project.wmss.controller;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.wmss.domain.Dmth004MainData;
import com.ruoyi.project.wmss.domain.WmssZclyTableData;
import com.ruoyi.project.wmss.service.IZclyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/wmss/ZCLY")
public class ZclyController extends BaseController {
@Autowired
private IZclyService zclyService;
// 获取主表数据
@GetMapping("/main-data")
public AjaxResult getMainData(@RequestParam String noc1523) {
Dmth004MainData data = zclyService.getMainData(noc1523);
if (data == null) {
return AjaxResult.error("未找到领用单号: " + noc1523);
}
return AjaxResult.success(data);
}
// 获取表格数据(SQL2)
@GetMapping("/table-data-sql2")
public TableDataInfo getTableDataBySQL2(
@RequestParam String cdc0270,
@RequestParam String cdc1386) {
startPage(); // 若依分页支持
List<WmssZclyTableData> list = zclyService.getTableDataBySQL2(cdc0270, cdc1386);
return getDataTable(list);
}
// 获取表格数据(SQL3)
@GetMapping("/table-data-sql3")
public TableDataInfo getTableDataBySQL3(@RequestParam String cdc0270) {
startPage(); // 若依分页支持
List<WmssZclyTableData> list = zclyService.getTableDataBySQL3(cdc0270);
return getDataTable(list);
}
}
```
### 关键实现说明:
1. **SQL参数处理**:
- 使用MyBatis的`#{}`语法进行参数绑定,防止SQL注入
- 对Oracle特有函数(如`DECODE`, `TRUNC(SYSDATE)`)保持原样
2. **字段映射**:
```xml
NO00027B AS tbNO00027B,
SU00355 AS tbSU00355,
'' AS tbSUN8529, <!-- 实际数量初始为空 -->
SU00355 AS tbSUN8530, <!-- 剩余数量初始等于在库数量 -->
DRNK AS tbDRNK
```
3. **分页支持**:
- 使用若依的`startPage()`和`getDataTable()`实现自动分页
- 前端表格可自动处理分页参数
4. **空值处理**:
- 使用`DECODE(T2.SUN6470_1, NULL, 0, T2.SUN6470_1)`处理可能的空值
- 使用`LEFT JOIN`确保即使没有匹配记录也能返回数据
5. **错误处理**:
- Controller层返回`AjaxResult.error()`处理查询为空的情况
- Service层可添加事务管理(根据业务需求)