mybatis xml文件热加载实现示例详解

下面我将为您详细讲解“mybatis xml文件热加载实现示例详解”的攻略。

一、什么是mybatis xml文件热加载?

mybatis xml文件热加载是指在mybatis项目运行时,可以动态修改对应的mapper.xml文件后,自动刷新SqlSessionFactory,实现数据库操作的实时更新,而不需要重新启动应用。

二、mybatis xml文件热加载实现步骤

下面将通过两条具体的实现示例,介绍mybatis xml文件热加载的实现步骤。

示例一:使用MapperScannerConfigurer实现mybatis xml文件热加载

步骤:

  1. 在mybatis-spring配置文件中添加MapperScannerConfigurer,扫描mapper接口,如下所示:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.mapper" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
  1. 在applicationContext.xml配置文件中添加MapperScannerConfigurer相关依赖:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:mybatis-config.xml" />
    <property name="mapperLocations" value="classpath*:mapper/*.xml" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.mapper" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>  
  1. 在mapper中添加代码实现xml热加载
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Configuration
@Component
@DependsOn("sqlSessionFactory")
public class ReloadMapperXmlConfiguration{

    private final SqlSessionFactory sqlSessionFactory;
    private final DataSource dataSource;

    @Autowired
    public ReloadMapperXmlConfiguration(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory,
                                       @Qualifier("dataSource") DataSource dataSource) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.dataSource = dataSource;
    }

    @PostConstruct
    public void initMapperXmlReload() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = TreeToList.tolist(resolver.getResources("classpath*:mapper/*.xml"));
        MapperXmlReload.reload(resources, dataSource, sqlSessionFactory);
    }
}
  1. 添加相关依赖包:
<!--mybatis-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.4</version>
</dependency>
<!--commons-dbcp-->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
  1. 启动项目,修改Mapper.xml文件,保存并刷新浏览器,查看效果。

示例二:使用MapperFactoryBean实现mybatis xml文件热加载

步骤:

  1. 创建MapperFactoryBean类,用于热加载mybatis.xml文件:
public class HotSwapMapperFactoryBean<T> extends MapperFactoryBean<T> {

    private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
    private final String mapperLocation;
    private SqlSessionFactory sqlSessionFactory;

    public HotSwapMapperFactoryBean(Class<T> mapperInterface, String mapperLocation) {
        super(mapperInterface);
        this.mapperLocation = mapperLocation;
    }

    @Override
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        super.setSqlSessionFactory(sqlSessionFactory);
        this.sqlSessionFactory = sqlSessionFactory;
        try {
            this.hotSwapReload();
        } catch (IOException e) {
            logger.error("IOException occurred.", e);
        }
    }

    public void hotSwapReload() throws IOException {
        Resource[] resources = resourceResolver.getResources(mapperLocation);
        HotSwapMapperXML hotSwapMapperXML = new HotSwapMapperXML();
        for (Resource r : resources) {
            hotSwapMapperXML.hotSwap(r.getInputStream(), sqlSessionFactory.getConfiguration());
        }
    }
}
  1. 创建自定义的MapperScannerConfigurer类,用于扫描Mapper接口:
public class HotSwapMapperScannerConfigurer extends MapperScannerConfigurer {

    private final String mapperLocation;

    public HotSwapMapperScannerConfigurer(String mapperLocation) {
        this.mapperLocation = mapperLocation;
    }

    @Override
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        super.setSqlSessionFactory(sqlSessionFactory);
        try {
            this.hotSwapReload();
        } catch (IOException e) {
            logger.error("IOException occurred.", e);
        }
    }

    public void hotSwapReload() throws IOException {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resourceResolver.getResources(mapperLocation);
        HotSwapMapperXML hotSwapMapperXML = new HotSwapMapperXML();
        for (Resource r : resources) {
            hotSwapMapperXML.hotSwap(r.getInputStream(), getSqlSessionFactory().getConfiguration());
        }
    }
}
  1. 创建HotSwapMapperXML类,用于执行热加载:
public class HotSwapMapperXML {

    private static final XPathFactory xPathFactory = XPathFactory.newInstance();
    private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();


    public void hotSwap(InputStream inputStream, Configuration configuration) throws IOException {
        try {
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse(inputStream);

            XPath xPath = xPathFactory.newXPath();
            XPathExpression selectNodes = xPath.compile("//mapper");
            NodeList nodes = (NodeList) selectNodes.evaluate(document, XPathConstants.NODESET);

            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                NamedNodeMap namedNodeMap = node.getAttributes();
                Node resourceNode = namedNodeMap.getNamedItem("resource");
                if (resourceNode != null) {
                    String resource = resourceNode.getNodeValue();
                    ResourcePatternResolver resolever = new PathMatchingResourcePatternResolver();
                    Resource[] resources = resolever.getResources(resource);
                    for (Resource mapperLocation : resources) {
                        InputStream resourceInputStream = mapperLocation.getInputStream();
                        try {
                            SQLMapperBuilder mapperBuilder = new XMLMapperBuilder(resourceInputStream, configuration, mapperLocation.toString(), configuration.getSqlFragments());
                            mapperBuilder.parse();
                        } finally {
                            resourceInputStream.close();
                        }
                    }
                    continue;
                }
                // ...
            }
        } catch (ParserConfigurationException | IOException | XPathExpressionException | SAXException e) {
            throw new IOException("Failed to parse mapping resource.", e);
        }
    }
}
  1. 在Mybatis XML配置文件中配置bean:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:mybatis-config.xml" />
    <property name="mapperLocations" value="classpath*:mapper/*.xml" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.mapper" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

<bean class="com.example.mapper.HotSwapMapperScannerConfigurer">
    <constructor-arg value="classpath*:mapper/*.xml" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
  1. 启动项目,修改Mapper.xml文件,保存并刷新浏览器,查看效果。

三、总结

通过上述两条示例,我们可以实现mybatis xml文件的热加载操作,并且无需重新启动应用程序,只需要修改对应的xml文件即可实时更新数据库操作。可以大大提高开发效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis xml文件热加载实现示例详解 - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • 小度智能音箱play和青春版哪款好 小度智能音箱play和青春版区别对比

    以下是“小度智能音箱play和青春版哪款好 小度智能音箱play和青春版区别对比”的完整攻略: 小度智能音箱play和青春版哪款好 小度智能音箱play和青春版区别对比 小度智能音箱play和青春版都是百度公司推出的智能音箱产品,它们都具有语音助手、音乐播放、智能家居控制等功能。但是,它们之间还是有一些区别的。下面是小度智能音箱play和青春版的详细对比。 …

    html 2023年5月18日
    00
  • HTML 编辑基础(菜鸟必看篇)

    HTML 编辑基础(菜鸟必看篇) 什么是 HTML? HTML(Hyper Text Markup Language),即超文本标记语言,是一种用于创建网页的标准标记语言。HTML 由一系列的标签(tag)组成,在每个标签中用来表示不同的网页内容。 HTML 编辑的基本流程 编写 HTML 代码 保存 HTML 文件 在浏览器中打开 HTML 文件 HTML…

    html 2023年5月30日
    00
  • Java基于JNDI 实现读写分离的示例代码

    针对Java基于JNDI 实现读写分离,我可以为您提供以下攻略。 什么是JNDI? JNDI(Java Naming and Directory Interface) 是一套用来访问各种命名和目录服务的API,来实现在Java平台上的“访问命名和目录服务”功能。 JNDI的读写分离 JNDI 可以通过配置多个数据源,实现读写分离的场景。对于读请求使用到的数据…

    html 2023年5月31日
    00
  • 小米随身wifi是什么 小米随身wifi怎么用

    小米随身WiFi是一款小巧便携的无线路由器,可以将有线网络转换为无线网络,方便用户在多个设备之间共享网络连接。以下是小米随身WiFi的使用攻略: 步骤1:连接小米随身WiFi 将小米随身WiFi插入电脑的USB接口。 等待电脑自动安装驱动程序。 打开电脑的无线网络设置,找到小米随身WiFi的SSID并连接。 步骤2:配置小米随身WiFi 打开浏览器,输入小米…

    html 2023年5月17日
    00
  • 使用JAXBContext轻松实现Java和xml的互相转换方式

    使用JAXB(Java Architecture for XML Binding)Context可以轻松实现Java对象和XML文档之间的转换,其过程主要包括以下几个步骤: 定义Java对象,使用注解的方式描述对象与XML元素的映射关系 创建JAXBContext实例 使用JAXBContext实例创建Marshaller和Unmarshaller对象,分别…

    html 2023年5月30日
    00
  • 字符集和字符编码(Charset & Encoding)

    字符集和字符编码 (Charset & Encoding) 在计算机中,字符集是一组可用字符的集合。每个字符都有一个唯一的数字标识,这个数字标识成为字符编码。因此,字符编码是指将字符映射到它们的唯一标识符的过程,这个过程是与特定的字符集相关的。 常见的字符集有 ASCII、ISO-8859、GB2312、GBK、UTF-8 等。不同的字符集支持的字符…

    html 2023年5月31日
    00
  • PHP基于XMLWriter操作xml的方法分析

    PHP基于XMLWriter操作XML的方法分析 概述 XMLWriter是PHP中一个内置的扩展,用于通过编程生成XML文档。 XMLWriter将XML文档作为流输出,因此可以由用户直接编写。由此,XMLWriter的用法相对于DOM库而言更加直观、更加高效. 本文将研究XMLWriter的用法,主要从以下几个方面来介绍: 创建XMLWriter对象 为…

    html 2023年5月30日
    00
  • asp控制xml数据库的经典代码

    首先,要使用ASP控制XML数据库,需要有基础的ASP编程知识和使用XML的经验。以下是ASP控制XML数据库的经典代码攻略: 准备工作 创建XML数据库文件并在其中添加数据,例如以下代码创建一个名为“test.xml”的文件,并添加一个名为“person”的元素及其属性: <?xml version="1.0" encoding=…

    html 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部