dom4J解析xml
dom4j需要引入的pom
<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.6</version> </dependency>
解析代码示例:
package com.bjgoodwill.oip.core.config; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.StringBufferInputStream; /** * Description:多数据源xml切换 */ public class DataSourceXMLChange { private final static Logger logger = LoggerFactory.getLogger(DataSourceXMLChange.class); /** * @Description:写入xml * @ isCheck true 为选中此xml,得去掉后缀的.hosp_bak_DB 、false为弃用此xml 得加上.hosp_bak_DB */ public static void updateXML(ClassPathResource classPathResource, boolean isCheck) throws IOException, DocumentException { File classPathResourceFile = classPathResource.getFile(); SAXReader saxreader = new SAXReader(); // 不验证xml的DTD,验证需要联网,否则验证会失败报错 saxreader.setEntityResolver(new EntityResolver() { @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource(new StringBufferInputStream("")); } }); Document document = saxreader.read(classPathResourceFile); Element element = (Element) document.selectSingleNode("/mapper"); Attribute attribute = element.attribute("namespace"); String namespace = attribute.getText(); if (isCheck) { if(namespace.contains(".hosp_bak_DB")){ namespace=namespace.substring(0,namespace.length()-12); attribute.setText(namespace); saveDocument(document, classPathResourceFile); } }else { if(!namespace.contains(".hosp_bak_DB")){ namespace=namespace+".hosp_bak_DB"; attribute.setText(namespace); saveDocument(document, classPathResourceFile); } } } /** * @Description:保存xml */ private static void saveDocument(Document document,File xmlFile) { XMLWriter writer = null; try { if (xmlFile.exists()){ xmlFile.delete(); } writer = new XMLWriter(new FileOutputStream(xmlFile), OutputFormat.createPrettyPrint()); writer.write(document); writer.close(); } catch (Exception e) { logger.error(xmlFile.getName()+":xml写入异常",e); } finally { if (writer != null) try { writer.close(); } catch (IOException e) { logger.error(xmlFile.getName()+"流关闭异常",e); } } } }
调用时,如切换不同数据源时加载不同语法对应的mybatis的xml,需要标记一个xml在正式运行时为无效状态,可以用如下代码:
package com.bjgoodwill.oip.core.config; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.tomcat.jdbc.pool.PoolConfiguration; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = {"com.common.dao.mydb"}, sqlSessionTemplateRef = "viewSqlSessionTemplate") public class DataSourceViewConfig { @Bean(name = "viewDataSource") @ConfigurationProperties(prefix = "spring.datasource.view") public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "viewSqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("viewDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); //加载对应数据源xml org.apache.tomcat.jdbc.pool.DataSource tomcatDataSource = (org.apache.tomcat.jdbc.pool.DataSource) dataSource; PoolConfiguration poolProperties = tomcatDataSource.getPoolProperties(); String driverClassName = poolProperties.getDriverClassName(); if (driverClassName.equals("com.mysql.jdbc.Driver")) { DataSourceXMLChange.updateXML(new ClassPathResource("com/common/dao/mapper/MapperSqlServer.xml"),false); DataSourceXMLChange.updateXML(new ClassPathResource("com/common/dao/mapper/MapperMysql.xml"),true); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/common/dao/mapper/MapperMysql.xml")); } else if (driverClassName.equals("com.microsoft.sqlserver.jdbc.SQLServerDriver")) { DataSourceXMLChange.updateXML(new ClassPathResource("com/common/dao/mapper/MapperSqlServer.xml"),true); DataSourceXMLChange.updateXML(new ClassPathResource("com/common/dao/mapper/MapperMysql.xml"),false); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/common/dao/mapper/MapperSqlServer.xml")); } bean.setConfigLocation(new ClassPathResource("mybatis-config.xml")); return bean.getObject(); } @Bean(name = "viewTransactionManager") public DataSourceTransactionManager testTransactionManager(@Qualifier("viewDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "viewSqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("viewSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
对应的多数据配置如下:
spring:
datasource:
view:
name: mssql_inpatient
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://192.168.188.188:1433;DatabaseName=db
username: root
password: root
# 使用druid数据源 Begin ##################################################
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 10
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
logSlowSql: true
# 使用druid数据源 End ######################################################
注意使用时如果环境是内网环境,无法联通外网,或者断网环境下,那么在使用dom4j解析xml时,如果xml文件头有dtd验证,默认会按给的url进行联网下载进行验证,如果网络不通,那么就会报错,所以才会有上面的去掉联网验证功能
参考: https://blog.csdn.net/youlianying/article/details/5908335