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 DmsWenjianBianhaoMapperXmlTest {
|
|
private static final List<String> MAPPERS = Arrays.asList(
|
"DmsWenjianBianhaoGuizeMapper",
|
"DmsWenjianBianhaoGuizeZixiangMapper",
|
"DmsWenjianBianhaoLiushuiJishuMapper",
|
"DmsWenjianBianhaoMapper",
|
"DmsWenjianBianhaoShenqingMapper",
|
"DmsWenjianMingchengBiangengShenqingMapper");
|
|
@Test
|
void serialCounterBindsStartOnlyForInitializationAndKeepsAtomicIncrement() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoLiushuiJishuMapper"));
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsWenjianBianhaoLiushuiJishuMapper.class.getName() + ".next");
|
assertTrue(statement.isFlushCacheRequired(), "同一批次相同分组不能复用本地查询缓存");
|
assertFalse(statement.isUseCache());
|
Map<String, Object> parameters = new HashMap<>();
|
parameters.put("tenantId", "tenant-1");
|
parameters.put("guizeLiushuihao", "family-1");
|
parameters.put("liushuiKey", "QC-{SERIAL:4}");
|
parameters.put("startValue", 100L);
|
org.apache.ibatis.mapping.BoundSql bound = statement.getBoundSql(parameters);
|
org.junit.jupiter.api.Assertions.assertEquals(
|
Arrays.asList("tenantId", "guizeLiushuihao", "liushuiKey", "startValue"),
|
bound.getParameterMappings().stream().map(p -> p.getProperty()).toList());
|
String sql = normalize(bound.getSql());
|
assertTrue(sql.contains("VALUES (?, ?, ?, ?) ON CONFLICT (f_tenant_id, guize_liushuihao, liushui_key_hash)"));
|
assertTrue(sql.contains("DO UPDATE SET dangqian_zhi = dms_wenjian_bianhao_gongxiang_jishu.dangqian_zhi + 1 WHERE dms_wenjian_bianhao_gongxiang_jishu.liushui_key = EXCLUDED.liushui_key RETURNING dangqian_zhi"));
|
}
|
|
@Test
|
void allFileNumberMappersUseXmlWithoutSelectStar() 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 ruleQueriesLoadQianpiyeSnapshotSourceWithExplicitMappings() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoGuizeMapper"));
|
for (String query : Arrays.asList("selectEnabled", "selectActiveById")) {
|
String statementId = DmsWenjianBianhaoGuizeMapper.class.getName() + "." + query;
|
assertMapping(configuration, statementId, "qianpiye_id", "qianpiyeId");
|
assertMapping(configuration, statementId, "qianpiye_files", "qianpiyeFiles");
|
String select = normalize(configuration.getMappedStatement(statementId)
|
.getBoundSql(new HashMap<>()).getSql()).split(" FROM ")[0];
|
assertTrue(select.contains("changqu"));
|
assertTrue(configuration.getMappedStatement(statementId).getResultMaps().get(0)
|
.getResultMappings().stream().anyMatch(mapping ->
|
"changqu".equals(mapping.getColumn()) && "changqu".equals(mapping.getProperty())));
|
assertTrue(select.contains("qianpiye_id"));
|
assertTrue(select.contains("qianpiye_files"));
|
}
|
}
|
|
@Test
|
void ruleVersionCheckExcludesTheCurrentRuleOnlyWhenAnIdIsProvided() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoGuizeMapper"));
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsWenjianBianhaoGuizeMapper.class.getName() + ".countByLiushuihaoAndBanbenhao");
|
Map<String, Object> parameters = new HashMap<>();
|
parameters.put("guizeLiushuihao", "serial-1");
|
parameters.put("banbenhao", "V2");
|
parameters.put("id", "rule-current");
|
assertTrue(normalize(statement.getBoundSql(parameters).getSql()).contains("f_id <> ?"));
|
|
parameters.put("id", "");
|
assertFalse(normalize(statement.getBoundSql(parameters).getSql()).contains("f_id <> ?"));
|
}
|
|
@Test
|
void ruleQueriesLoadApprovalStateAndOnlyOfferEnabledApprovedRules() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoGuizeMapper"));
|
for (String query : Arrays.asList("selectEnabled", "selectActiveById")) {
|
String statementId = DmsWenjianBianhaoGuizeMapper.class.getName() + "." + query;
|
assertMapping(configuration, statementId, "banbenhao", "banbenhao");
|
assertMapping(configuration, statementId, "f_flow_state", "flowState");
|
String sql = normalize(configuration.getMappedStatement(statementId)
|
.getBoundSql(new HashMap<>()).getSql());
|
assertTrue(sql.split(" FROM ")[0].contains("banbenhao"));
|
assertTrue(sql.split(" FROM ")[0].contains("f_flow_state"));
|
if ("selectEnabled".equals(query)) {
|
assertTrue(sql.contains("AND biz_enabled = 'enabled'"));
|
assertTrue(sql.contains("AND f_flow_state = 2"));
|
assertFalse(sql.contains("biz_enabled IS NULL"));
|
assertFalse(sql.contains("biz_enabled <>"));
|
}
|
}
|
}
|
|
@Test
|
void ruleAndPartQueriesMapCompleteSourceRows() throws IOException {
|
for (String mapper : Arrays.asList("DmsWenjianBianhaoGuizeMapper",
|
"DmsWenjianBianhaoGuizeZixiangMapper")) {
|
Configuration configuration = parse(resource(mapper));
|
boolean main = mapper.equals("DmsWenjianBianhaoGuizeMapper");
|
for (String query : main ? Arrays.asList("selectEnabled", "selectActiveById")
|
: Arrays.asList("selectActiveByRule")) {
|
String statementId = "jnpf.dmsMapper." + mapper + "." + query;
|
assertMapping(configuration, statementId, "snapshot_data", "snapshotData");
|
String sql = normalize(configuration.getMappedStatement(statementId)
|
.getBoundSql(new HashMap<>()).getSql());
|
assertTrue(sql.contains("to_jsonb(" + (main ? "r" : "p") + ")::text AS snapshot_data"));
|
}
|
}
|
}
|
|
@Test
|
void customNumberContentIsLoadedWithApplicationRows() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoMapper"));
|
for (String query : List.of("selectByApplication", "selectByApplicationForUpdate")) {
|
String id = DmsWenjianBianhaoMapper.class.getName() + "." + query;
|
assertMapping(configuration, id, "zidingyi_neirong", "zidingyiNeirong");
|
assertTrue(normalize(configuration.getMappedStatement(id).getBoundSql(new HashMap<>()).getSql())
|
.split(" FROM ")[0].contains("zidingyi_neirong"));
|
}
|
}
|
|
@Test
|
void applicationFlowStateHasExplicitResultMapping() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoShenqingMapper"));
|
assertMapping(configuration,
|
DmsWenjianBianhaoShenqingMapper.class.getName() + ".selectByFlowForUpdate",
|
"f_flow_state", "flowState");
|
}
|
|
@Test
|
void nameChangeFlowStateHasExplicitResultMapping() throws IOException {
|
Configuration configuration = parse(
|
resource("DmsWenjianMingchengBiangengShenqingMapper"));
|
assertMapping(configuration,
|
DmsWenjianMingchengBiangengShenqingMapper.class.getName()
|
+ ".selectByFlowForUpdate",
|
"f_flow_state", "flowState");
|
}
|
|
@Test
|
void usingNumberCandidatesExcludeActiveNameChangesButEchoRemainsAvailable()
|
throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoMapper"));
|
String statementId = DmsWenjianBianhaoMapper.class.getName() + ".selectUsingPage";
|
Map<String, Object> parameters = new HashMap<>();
|
parameters.put("bianhaoId", "");
|
parameters.put("keyword", "");
|
String candidateSql = normalize(configuration.getMappedStatement(statementId)
|
.getBoundSql(parameters).getSql());
|
assertTrue(candidateSql.contains("NOT EXISTS"));
|
assertTrue(candidateSql.contains("c.f_flow_state IN (1, 5, 6, 8, 10)"));
|
|
parameters.put("bianhaoId", "number-1");
|
String echoSql = normalize(configuration.getMappedStatement(statementId)
|
.getBoundSql(parameters).getSql());
|
assertFalse(echoSql.contains("NOT EXISTS"));
|
assertTrue(echoSql.contains("b.f_id = ?"));
|
}
|
|
@Test
|
void newNumberCandidatesExcludeHistoricalResourcesWithoutBreakingEcho() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianBianhaoMapper"));
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsWenjianBianhaoMapper.class.getName() + ".selectAvailableNewPage");
|
Map<String, Object> parameters = new HashMap<>();
|
parameters.put("bianhaoId", "");
|
parameters.put("keyword", "");
|
String candidateSql = normalize(statement.getBoundSql(parameters).getSql());
|
assertTrue(candidateSql.contains("FROM dms_wenjian_ziyuan r"));
|
assertTrue(candidateSql.contains("r.wenjian_bianhao_id = b.f_id OR r.wenjian_bianhao = b.wenjian_bianhao"));
|
assertFalse(candidateSql.contains("r.f_delete_mark"));
|
|
parameters.put("bianhaoId", "number-1");
|
String echoSql = normalize(statement.getBoundSql(parameters).getSql());
|
assertFalse(echoSql.contains("FROM dms_wenjian_ziyuan r"));
|
assertTrue(echoSql.contains("b.f_id = ?"));
|
}
|
|
private Configuration parse(String resource) throws IOException {
|
Configuration configuration = new Configuration();
|
try (InputStream common = Resources.getResourceAsStream("mapper/BusinessFileOccupancyMapper.xml")) {
|
new XMLMapperBuilder(common,configuration,"mapper/BusinessFileOccupancyMapper.xml",configuration.getSqlFragments()).parse();
|
}
|
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 normalize(String sql) {
|
return sql.replaceAll("\\s+", " ").trim();
|
}
|
|
private String resource(String mapper) {
|
return "mapper/" + mapper + ".xml";
|
}
|
}
|