package jnpf.dmsMapper; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.io.Resources; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ResultMapping; import org.apache.ibatis.session.Configuration; import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; class DmsWenjianBanbenMapperXmlTest { private static final List MAPPERS = Arrays.asList( "DmsWenjianZiyuanMapper", "DmsWenjianBanbenMapper", "DmsWenjianGuanxiMapper", "DmsWenjianXinzengShenheMapper", "DmsWenjianXinzengShenheJiluMingxiMapper", "DmsWenjianXiudingShenqingMapper", "DmsWenjianXiudingShenqingZixiangMapper", "DmsWenjianXiudingShenheMapper", "DmsXiudingKanwuMapper", "DmsWenjianXiudingShenheJiluMingxiMapper", "DmsWenjianGuanlianMingxiMapper", "DmsWenjianXiazaiShenqingMapper", "DmsWenjianXiazaiShenqingDetailMapper", "DmsWenjianDayinShenqingMapper", "DmsWenjianDayinShenqingDetailMapper"); @Test void allVersionMappersParseAndAvoidSelectStar() throws IOException { for (String mapper : MAPPERS) { String resource = resource(mapper); String xml; try (Reader reader = Resources.getResourceAsReader(resource)) { xml = read(reader); } assertFalse(xml.toUpperCase().contains("SELECT *"), resource); parse(resource); } } @Test void flowAndVersionFieldsHaveExplicitMappings() throws IOException { Configuration newAudit = parse(resource("DmsWenjianXinzengShenheMapper")); assertMapping(newAudit, DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate", "f_flow_state", "flowState"); assertMapping(newAudit, DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate", "shengxiao_wenjian_banben_id", "shengxiaoWenjianBanbenId"); assertMapping(newAudit, DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate", "shifou_peixun", "shifouPeixun"); assertMapping(newAudit, DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate", "peixun_wancheng_riqi", "peixunWanchengRiqi"); assertTrue(newAudit.getMappedStatement( DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate") .getBoundSql(null).getSql().contains("peixun_wancheng_riqi")); Configuration version = parse(resource("DmsWenjianBanbenMapper")); assertMapping(version, DmsWenjianBanbenMapper.class.getName() + ".selectCurrentByFileId", "yuan_wenjian_banben_id", "yuanWenjianBanbenId"); assertMapping(version, DmsWenjianBanbenMapper.class.getName() + ".selectById", "bei_tidai_yuanyin", "beiTidaiYuanyin"); Configuration file = parse(resource("DmsWenjianZiyuanMapper")); assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate", "youxiao_qi_zhi", "youxiaoQiZhi"); assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate", "fushen_riqi", "fushenRiqi"); assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate", "fushen_shenqing_id", "fushenShenqingId"); assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate", "jinyong_laiyuan", "jinyongLaiyuan"); Configuration revisionAudit = parse(resource("DmsWenjianXiudingShenheMapper")); assertMapping(revisionAudit, DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate", "xiuding_shenqing_zixiang_id", "xiudingShenqingZixiangId"); assertMapping(revisionAudit, DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate", "shifou_peixun", "shifouPeixun"); assertMapping(revisionAudit, DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate", "peixun_wancheng_riqi", "peixunWanchengRiqi"); assertTrue(revisionAudit.getMappedStatement( DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate") .getBoundSql(null).getSql().contains("peixun_wancheng_riqi")); Configuration revisionDetail = parse(resource("DmsWenjianXiudingShenqingZixiangMapper")); assertMapping(revisionDetail, DmsWenjianXiudingShenqingZixiangMapper.class.getName() + ".selectByIdForUpdate", "yuan_wenjian_banben_id", "yuanWenjianBanbenId"); } @Test void resourceAdvanceChecksExpectedVersionId() throws IOException { Configuration configuration = parse(resource("DmsWenjianZiyuanMapper")); MappedStatement statement = configuration.getMappedStatement( DmsWenjianZiyuanMapper.class.getName() + ".advanceCurrentVersion"); String sql = statement.getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(sql.contains("dangqian_banben_id = ?")); assertTrue(sql.contains("biz_status = 'effective'")); } @Test void reviewMetadataDoesNotOverwriteTheCenterProjectedDeadline() throws IOException { Configuration configuration = parse(resource("DmsWenjianZiyuanMapper")); MappedStatement statement = configuration.getMappedStatement( DmsWenjianZiyuanMapper.class.getName() + ".updateReviewExtension"); Map params = new HashMap<>(); params.put("wenjianId", "file-1"); params.put("yanqiZhi", new java.util.Date()); params.put("fushenShenqingId", "application-1"); params.put("fushenRiqi", "2026-09-14 12:30:45"); String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " "); org.junit.jupiter.api.Assertions.assertFalse(sql.contains("youxiao_qi_zhi = ?")); assertTrue(sql.contains("fushen_shenqing_id = ?")); assertTrue(sql.contains("fushen_riqi = ?")); assertTrue(sql.contains("f_id = ?")); assertTrue(sql.contains("f_delete_mark IS NULL")); } @Test void resourceFileVersionLookupUsesActiveResource() throws IOException { Configuration configuration = parse(resource("DmsWenjianZiyuanMapper")); MappedStatement statement = configuration.getMappedStatement( DmsWenjianZiyuanMapper.class.getName() + ".selectFileVersionIdByWenjianId"); Map params = new HashMap<>(); params.put("wenjianId", "file-1"); String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " "); assertTrue(sql.contains("SELECT wenjian_zhongxin_banben_id")); assertTrue(sql.contains("f_id = ?")); assertTrue(sql.contains("f_delete_mark IS NULL")); } @Test void reservedNumberLookupsIncludeDeletedResources() throws IOException { Configuration configuration = parse(resource("DmsWenjianZiyuanMapper")); for (String method : Arrays.asList("selectByNumberForUpdate", "selectByNumberDetailForUpdate")) { String sql = configuration.getMappedStatement( DmsWenjianZiyuanMapper.class.getName() + "." + method) .getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(sql.contains("f_tenant_id = ?")); assertTrue(sql.contains("FOR UPDATE")); assertFalse(sql.contains("f_delete_mark IS NULL")); } } @Test void workflowDownloadLookupsLockOnlyActiveTenantRows() throws IOException { Configuration resources = parse(resource("DmsWenjianZiyuanMapper")); for (String method : Arrays.asList( "selectActiveByNumberForUpdate", "selectActiveByNumberDetailForUpdate")) { String sql = resources.getMappedStatement( DmsWenjianZiyuanMapper.class.getName() + "." + method) .getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(sql.contains("f_tenant_id = ?")); assertTrue(sql.contains("f_delete_mark IS NULL")); assertTrue(sql.contains("FOR UPDATE")); } Configuration requests = parse(resource("DmsWenjianXiazaiShenqingMapper")); String requestSql = requests.getMappedStatement( DmsWenjianXiazaiShenqingMapper.class.getName() + ".selectByFlowForUpdate") .getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(requestSql.contains("f_tenant_id = ?")); assertTrue(requestSql.contains("f_delete_mark IS NULL")); assertTrue(requestSql.contains("FOR UPDATE")); Configuration details = parse(resource("DmsWenjianXiazaiShenqingDetailMapper")); String detailSql = details.getMappedStatement( DmsWenjianXiazaiShenqingDetailMapper.class.getName() + ".selectByRequestForUpdate") .getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(detailSql.contains("f_tenant_id = ?")); assertTrue(detailSql.contains("f_delete_mark IS NULL")); assertTrue(detailSql.contains("FOR UPDATE")); Configuration printRequests = parse(resource("DmsWenjianDayinShenqingMapper")); String printRequestSql = printRequests.getMappedStatement( DmsWenjianDayinShenqingMapper.class.getName() + ".selectByFlowForUpdate") .getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(printRequestSql.contains("f_tenant_id = ?")); assertTrue(printRequestSql.contains("f_delete_mark IS NULL")); assertTrue(printRequestSql.contains("FOR UPDATE")); Configuration printDetails = parse(resource("DmsWenjianDayinShenqingDetailMapper")); String printDetailSql = printDetails.getMappedStatement( DmsWenjianDayinShenqingDetailMapper.class.getName() + ".selectByRequestForUpdate") .getBoundSql(null).getSql().replaceAll("\\s+", " "); assertTrue(printDetailSql.contains("f_tenant_id = ?")); assertTrue(printDetailSql.contains("f_delete_mark IS NULL")); assertTrue(printDetailSql.contains("FOR UPDATE")); } private Configuration parse(String resource) throws IOException { Configuration configuration = new Configuration(); try (InputStream input = Resources.getResourceAsStream(resource)) { XMLMapperBuilder builder = new XMLMapperBuilder( input, configuration, resource, configuration.getSqlFragments()); builder.parse(); } return configuration; } private void assertMapping(Configuration configuration, String statementId, String column, String property) { MappedStatement statement = configuration.getMappedStatement(statementId); boolean mapped = statement.getResultMaps().stream() .flatMap(resultMap -> resultMap.getResultMappings().stream()) .anyMatch(mapping -> matches(mapping, column, property)); assertTrue(mapped, column + " must map explicitly to " + property); } private boolean matches(ResultMapping mapping, String column, String property) { return column.equals(mapping.getColumn()) && property.equals(mapping.getProperty()); } private String read(Reader reader) throws IOException { StringBuilder result = new StringBuilder(); char[] buffer = new char[2048]; int length; while ((length = reader.read(buffer)) >= 0) { result.append(buffer, 0, length); } return result.toString(); } private String resource(String mapper) { return "mapper/" + mapper + ".xml"; } }