From 9441ae9cbf0ae6322a20ea0cff65a78596810cf2 Mon Sep 17 00:00:00 2001 From: niushuai Date: Tue, 25 Feb 2025 18:01:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AF=B9mybatis-plus?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 ++ .../xml/reloader/XmlMapperReLoader.java | 80 ++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 69f688f..8c79989 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ 1.8 1.8 + UTF-8 @@ -37,5 +38,11 @@ 3.5.3 provided + + + javax.annotation + javax.annotation-api + 1.3.2 + \ No newline at end of file diff --git a/src/main/java/com/github/niushuai233/mybatis/xml/reloader/XmlMapperReLoader.java b/src/main/java/com/github/niushuai233/mybatis/xml/reloader/XmlMapperReLoader.java index 8cec51e..aa4e61a 100644 --- a/src/main/java/com/github/niushuai233/mybatis/xml/reloader/XmlMapperReLoader.java +++ b/src/main/java/com/github/niushuai233/mybatis/xml/reloader/XmlMapperReLoader.java @@ -1,6 +1,11 @@ package com.github.niushuai233.mybatis.xml.reloader; import org.apache.ibatis.builder.xml.XMLMapperBuilder; +import org.apache.ibatis.builder.xml.XMLMapperEntityResolver; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.ResultMap; +import org.apache.ibatis.parsing.XNode; +import org.apache.ibatis.parsing.XPathParser; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSessionFactory; import org.slf4j.Logger; @@ -71,6 +76,7 @@ public class XmlMapperReLoader { public void readMapperXml() { try { Configuration configuration = sqlSessionFactory.getConfiguration(); + // step.1 扫描文件 try { this.scanMapperXml(); @@ -78,18 +84,29 @@ public class XmlMapperReLoader { throw new RuntimeException("package " + packageSearchPath + " search path error"); } + boolean mybatisPlusORM = true; + // 2 判断是否有文件发生了变化 if (this.isChanged()) { // 2.1 清理 - this.removeConfig(configuration); + if (!mybatisPlusORM) { + // 若是mybatis时 非mp + this.removeConfig(configuration); + } // 2.2 重新加载 for (org.springframework.core.io.Resource configLocation : mapperLocations) { try { - XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configLocation.getInputStream(), configuration, configLocation.toString(), configuration.getSqlFragments()); + + if (mybatisPlusORM) { + // 若是mp时 + mybatisPlusRemoveConfig(sqlSessionFactory, configuration, configLocation); + } + + XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder( + configLocation.getInputStream(), configuration, configLocation.toString(), configuration.getSqlFragments()); xmlMapperBuilder.parse(); } catch (IOException e) { log.info("Mapper [" + configLocation.getFilename() + "] doesn't exist or the content format is wrong"); - continue; } } } @@ -105,6 +122,52 @@ public class XmlMapperReLoader { } } + private void mybatisPlusRemoveConfig(SqlSessionFactory sqlSessionFactory, Configuration configuration, Resource configLocation) { + XPathParser parser = null; + try { + parser = new XPathParser(configLocation.getInputStream(), true, configuration.getVariables(), new XMLMapperEntityResolver()); + } catch (Exception e) { + log.error("Could not parse configuration", e); + } + XNode mapperXNode = parser.evalNode("/mapper"); + String namespace = mapperXNode.getStringAttribute("namespace"); + + Map resultMapsMap = (Map) getFieldValue(configuration, configuration.getClass(), "resultMaps"); + List resultMapNodeList = mapperXNode.evalNodes("/mapper/resultMap"); + for (XNode node : resultMapNodeList) { + String id = node.getStringAttribute("id", node.getValueBasedIdentifier()); + Iterator> iterator = resultMapsMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry next = iterator.next(); + String key = next.getKey(); + if (key.contains(namespace + "." + id)) { + iterator.remove(); + } + if (key.contains(namespace + ".mapper_resultMap")) { + iterator.remove(); + } + } + } + + Map sqlFragmentsMap = (Map) getFieldValue(configuration, configuration.getClass(), "sqlFragments"); + List sqlNodeList = mapperXNode.evalNodes("/mapper/sql"); + for (XNode sqlNode : sqlNodeList) { + String id = sqlNode.getStringAttribute("id", sqlNode.getValueBasedIdentifier()); + sqlFragmentsMap.remove(namespace + "." + id); + } + + Map mappedStatementsMap = (Map) getFieldValue(configuration, configuration.getClass(), "mappedStatements"); + List _4nodeList = mapperXNode.evalNodes("select|insert|update|delete"); + for (XNode _4node : _4nodeList) { + String id = _4node.getStringAttribute("id", _4node.getValueBasedIdentifier()); + mappedStatementsMap.remove(namespace + "." + id); + } + + Set loadedResourcesSet = (Set) getFieldValue(configuration, configuration.getClass().getSuperclass(), "loadedResources"); + loadedResourcesSet.clear(); + + } + /** * 扫描xml文件所在的路径 * @@ -187,4 +250,15 @@ public class XmlMapperReLoader { } return flag; } + + private static Object getFieldValue(Configuration targetConfiguration, Class targetClass, String filedName) { + try { + Field declaredField = targetClass.getDeclaredField(filedName); + declaredField.setAccessible(true); + return declaredField.get(targetConfiguration); + } catch (Exception e) { + log.error("无法通过反射获取对象值 class: {}, field: {}, 异常信息: {}", targetClass.getName(), filedName, e.getMessage()); + throw new RuntimeException(e); + } + } } \ No newline at end of file