mybatis 在运行时注入 Mapper xml
mybatis inject Mapper xml while runtime
在 Mybatis 中,是否可以将基于 java 的配置与基于 xml 的映射器混合使用?
在配置mybatis时,我想使用POJO,因为我可以在运行时配置。
当注册 mapper 到 Configuration 时,我必须生成 mapper.xml 在运行时。
我知道有
<mappers>
<mapper resource = "mybatis/Student.xml"/>
</mappers>
可以嵌入到mybatis配置文件中
但是我想在运行时注入不同的Mapper,甚至,我想在运行时生成一个不同的Mapperxml文件并注入到MybatisConfiguration
.
这可能吗?如果是这样,我该怎么做?谢谢。
是的,您可以在运行时使用 SqlSessionFactory 工厂创建新的 Mapper 对象:
xml:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis/mybatis.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
-- 更新于 2017-05-09,加载 mapper.xml ---
这是我从 mybatis-3.4.0-sources.jar!org/apache/ibatis/builder/xmlXMLConfigBuilder
中找到的代码
我想新的 mapper.xml 文件可以被
解析并注册到配置中
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
-- org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XNode 父节点)--
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
ErrorContext.instance().resource(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
}
// else
// ....
}
// else
// ....
}
这里是org.apache.ibatis.builder.xml.XMLMapperBuilder#parse()
的过程
public void parse() {
if (!configuration.isResourceLoaded(resource)) {
configurationElement(parser.evalNode("/mapper"));
configuration.addLoadedResource(resource);
bindMapperForNamespace();
}
parsePendingResultMaps();
parsePendingChacheRefs();
parsePendingStatements();
}
是的,您可以通过编程方式添加映射器。假设您有一个名为 StudentMapper
的映射器。它可能有注释,或者 class 路径上可能有一个映射文件,具有匹配的完全限定 class 名称。然后你可以像这样添加映射器:
SqlSessionFactory factory = ...
factory.getConfiguration().addMapper(StudentMapper.class);
... 并像这样使用它:
Student student;
try (SqlSession session = factory.openSession()) {
StudentMapper mapper = session.getMapper(StudentMapper.class);
student = mapper.get(id);
}
在 Mybatis 中,是否可以将基于 java 的配置与基于 xml 的映射器混合使用?
在配置mybatis时,我想使用POJO,因为我可以在运行时配置。
当注册 mapper 到 Configuration 时,我必须生成 mapper.xml 在运行时。
我知道有
<mappers>
<mapper resource = "mybatis/Student.xml"/>
</mappers>
可以嵌入到mybatis配置文件中
但是我想在运行时注入不同的Mapper,甚至,我想在运行时生成一个不同的Mapperxml文件并注入到MybatisConfiguration
.
这可能吗?如果是这样,我该怎么做?谢谢。
是的,您可以在运行时使用 SqlSessionFactory 工厂创建新的 Mapper 对象:
xml:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis/mybatis.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
-- 更新于 2017-05-09,加载 mapper.xml --- 这是我从 mybatis-3.4.0-sources.jar!org/apache/ibatis/builder/xmlXMLConfigBuilder
中找到的代码我想新的 mapper.xml 文件可以被
解析并注册到配置中InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
-- org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XNode 父节点)--
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
ErrorContext.instance().resource(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
}
// else
// ....
}
// else
// ....
}
这里是org.apache.ibatis.builder.xml.XMLMapperBuilder#parse()
的过程public void parse() {
if (!configuration.isResourceLoaded(resource)) {
configurationElement(parser.evalNode("/mapper"));
configuration.addLoadedResource(resource);
bindMapperForNamespace();
}
parsePendingResultMaps();
parsePendingChacheRefs();
parsePendingStatements();
}
是的,您可以通过编程方式添加映射器。假设您有一个名为 StudentMapper
的映射器。它可能有注释,或者 class 路径上可能有一个映射文件,具有匹配的完全限定 class 名称。然后你可以像这样添加映射器:
SqlSessionFactory factory = ...
factory.getConfiguration().addMapper(StudentMapper.class);
... 并像这样使用它:
Student student;
try (SqlSession session = factory.openSession()) {
StudentMapper mapper = session.getMapper(StudentMapper.class);
student = mapper.get(id);
}