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

 

posted @ 2019-01-30 13:36  关键步就几步  阅读(577)  评论(0编辑  收藏  举报