修复数据映射:对齐住宿有效状态关系并修正课次考勤名册参数契约
This commit is contained in:
1 parent
1149c2b141
commit
b1d5a999ca
3 files changed
+143
-13
No files matched your search
@@ -85,16 +85,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
a.accommodation_status as accommodationStatus
|
||||
from train_enrollment e
|
||||
left join train_student s on e.student_id = s.s_id
|
||||
left join (
|
||||
select a1.enrollment_id, a1.dorm_id, a1.bed_no, a1.accommodation_status
|
||||
from train_accommodation a1
|
||||
inner join (
|
||||
select enrollment_id, max(accommodation_id) as max_id
|
||||
from train_accommodation
|
||||
group by enrollment_id
|
||||
) a2 on a1.accommodation_id = a2.max_id
|
||||
) a on e.enrollment_id = a.enrollment_id
|
||||
left join train_dormitory_info d on a.dorm_id = d.dorm_id
|
||||
left join train_accommodation a on e.enrollment_id = a.enrollment_id and a.accommodation_status in (0, 1)
|
||||
left join train_dormitory_info d on a.dorm_id = d.dorm_id and d.del_flag = '0'
|
||||
<where>
|
||||
e.plan_id = #{planId}
|
||||
<if test="studentName != null and studentName != ''">
|
||||
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package com.ruoyi.train.mapper;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.junit.Test;
|
||||
import com.ruoyi.train.domain.TrainClassPlan;
|
||||
import com.ruoyi.train.domain.TrainEnrollment;
|
||||
import com.ruoyi.train.domain.query.EnrollmentQuery;
|
||||
import com.ruoyi.train.domain.vo.EnrollmentItemVO;
|
||||
|
||||
/**
|
||||
* 参训登记 Mapper 数据映射契约与合规性保护测试 (TrainEnrollmentMapperContractTest)
|
||||
* 验证住宿关联只使用真实系统表 train_accommodation 与 train_dormitory_info,
|
||||
* 严禁引用历史不存在的假表,且 MyBatis 映射可成功解析。
|
||||
*/
|
||||
public class TrainEnrollmentMapperContractTest
|
||||
{
|
||||
@Test
|
||||
public void enrollmentMapperMustOnlyReferenceRealAccommodationTables() throws Exception
|
||||
{
|
||||
String xml = loadMapperXml("TrainEnrollmentMapper.xml");
|
||||
|
||||
// 1. 验证必须引用的真实系统表
|
||||
assertContains(xml,
|
||||
"train_enrollment",
|
||||
"train_student",
|
||||
"train_accommodation",
|
||||
"train_dormitory_info"
|
||||
);
|
||||
|
||||
// 2. 验证有效状态与逻辑删除过滤约束
|
||||
assertContains(xml,
|
||||
"a.accommodation_status in (0, 1)",
|
||||
"d.del_flag = '0'"
|
||||
);
|
||||
|
||||
// 3. 严禁引用不存在的临时假表
|
||||
assertOmits(xml,
|
||||
"train_dorm_assignment",
|
||||
"train_dorm_room",
|
||||
"train_dorm_bed",
|
||||
"train_attendance"
|
||||
);
|
||||
|
||||
// 4. 严禁使用非通用 PG 专有方言 DISTINCT ON
|
||||
assertOmits(xml, "distinct on");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enrollmentMapperXmlParsesValidMyBatisMappedStatements() throws Exception
|
||||
{
|
||||
Configuration configuration = new Configuration();
|
||||
// 注册必要类型别名以便 XMLMapperBuilder 解析
|
||||
configuration.getTypeAliasRegistry().registerAlias("TrainEnrollment", TrainEnrollment.class);
|
||||
configuration.getTypeAliasRegistry().registerAlias("TrainClassPlan", TrainClassPlan.class);
|
||||
configuration.getTypeAliasRegistry().registerAlias("EnrollmentQuery", EnrollmentQuery.class);
|
||||
configuration.getTypeAliasRegistry().registerAlias("EnrollmentItemVO", EnrollmentItemVO.class);
|
||||
|
||||
try (InputStream inputStream = getClass().getResourceAsStream("/mapper/train/TrainEnrollmentMapper.xml"))
|
||||
{
|
||||
assertNotNull("TrainEnrollmentMapper.xml must exist in classpath", inputStream);
|
||||
XMLMapperBuilder mapperParser = new XMLMapperBuilder(
|
||||
inputStream,
|
||||
configuration,
|
||||
"/mapper/train/TrainEnrollmentMapper.xml",
|
||||
configuration.getSqlFragments()
|
||||
);
|
||||
mapperParser.parse();
|
||||
}
|
||||
|
||||
// 验证 selectEnrollmentItemList 语句成功生成
|
||||
String statementId = "com.ruoyi.train.mapper.TrainEnrollmentMapper.selectEnrollmentItemList";
|
||||
assertTrue("Statement must be registered in configuration", configuration.hasStatement(statementId));
|
||||
MappedStatement ms = configuration.getMappedStatement(statementId);
|
||||
assertNotNull(ms);
|
||||
assertEquals(EnrollmentItemVO.class, ms.getResultMaps().get(0).getType());
|
||||
|
||||
// 验证 EnrollmentItemVO 具备映射所需住宿属性
|
||||
assertHasProperty(EnrollmentItemVO.class, "getDormBuilding");
|
||||
assertHasProperty(EnrollmentItemVO.class, "getDormRoom");
|
||||
assertHasProperty(EnrollmentItemVO.class, "getBedNo");
|
||||
assertHasProperty(EnrollmentItemVO.class, "getAccommodationStatus");
|
||||
}
|
||||
|
||||
private String loadMapperXml(String name) throws Exception
|
||||
{
|
||||
try (InputStream input = getClass().getResourceAsStream("/mapper/train/" + name))
|
||||
{
|
||||
assertNotNull("missing mapper " + name, input);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = input.read(buffer)) != -1)
|
||||
{
|
||||
output.write(buffer, 0, length);
|
||||
}
|
||||
return new String(output.toByteArray(), StandardCharsets.UTF_8).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertContains(String content, String... tokens)
|
||||
{
|
||||
for (String token : tokens)
|
||||
{
|
||||
assertTrue("Expected content to contain: " + token, content.contains(token.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertOmits(String content, String... tokens)
|
||||
{
|
||||
for (String token : tokens)
|
||||
{
|
||||
assertFalse("Expected content to omit: " + token, content.contains(token.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertHasProperty(Class<?> clazz, String getterName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = clazz.getMethod(getterName);
|
||||
assertNotNull("Getter must exist: " + getterName, method);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new AssertionError("Class " + clazz.getSimpleName() + " missing method: " + getterName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user