下面我将为您详细讲解“mybatis xml文件热加载实现示例详解”的攻略。
一、什么是mybatis xml文件热加载?
mybatis xml文件热加载是指在mybatis项目运行时,可以动态修改对应的mapper.xml文件后,自动刷新SqlSessionFactory,实现数据库操作的实时更新,而不需要重新启动应用。
二、mybatis xml文件热加载实现步骤
下面将通过两条具体的实现示例,介绍mybatis xml文件热加载的实现步骤。
示例一:使用MapperScannerConfigurer实现mybatis xml文件热加载
步骤:
- 在mybatis-spring配置文件中添加MapperScannerConfigurer,扫描mapper接口,如下所示:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
- 在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>
- 在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);
}
}
- 添加相关依赖包:
<!--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>
- 启动项目,修改Mapper.xml文件,保存并刷新浏览器,查看效果。
示例二:使用MapperFactoryBean实现mybatis xml文件热加载
步骤:
- 创建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());
}
}
}
- 创建自定义的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());
}
}
}
- 创建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);
}
}
}
- 在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>
- 启动项目,修改Mapper.xml文件,保存并刷新浏览器,查看效果。
三、总结
通过上述两条示例,我们可以实现mybatis xml文件的热加载操作,并且无需重新启动应用程序,只需要修改对应的xml文件即可实时更新数据库操作。可以大大提高开发效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis xml文件热加载实现示例详解 - Python技术站