在spring-mybatis中使用类路径配置Map器位置:*

vlf7wbxs  于 2023-01-09  发布在  Spring
关注(0)|答案(4)|浏览(188)

所以我希望我们能成功

@Bean
@ConfigurationProperties("datasource.mybatis-factory")
public SqlSessionFactoryBean sqlSessionFactoryBean() {
  SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource());
  return sqlSessionFactoryBean;
}

有财产(除其他外)

datasource.mybatis-factory.mapper-locations=classpath*:sqlmap/*.xml

但是,即使文件存在,它也会失败:

Caused by: java.io.FileNotFoundException: class path resource [classpath*:sqlmap/*.xml] cannot be opened because it does not exist

看一下setMapperLocations(),我没有做错任何事情,他们显然希望我使用classpath*:...

/**
 * Set locations of MyBatis mapper files that are going to be merged into the {@code SqlSessionFactory} configuration
 * at runtime.
 *
 * This is an alternative to specifying "<sqlmapper>" entries in an MyBatis config file. This property being
 * based on Spring's resource abstraction also allows for specifying resource patterns here: e.g.
 * "classpath*:sqlmap/*-mapper.xml".
 *
 * @param mapperLocations
 *          location of MyBatis mapper files
 */
public void setMapperLocations(Resource... mapperLocations) {
  this.mapperLocations = mapperLocations;
}

再往下看代码,就是这样:

for (Resource mapperLocation : this.mapperLocations) {
      if (mapperLocation == null) {
        continue;
      }
      try {
        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
            targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
        xmlMapperBuilder.parse();

没有代码可以将classpath*:sqlmap/*.xml转换成可打开的资源,或者至少我没有看到它。

  • 解决方法:*

我现在有什么和正在工作(注意,我不使用datasource.mybatis-factory.mapper-locations,因为这将再次覆盖我的设置):

@Bean
@ConfigurationProperties("datasource.mybatis-factory")
public SqlSessionFactoryBean sqlSessionFactoryBean(
    @Value("${datasource.mybatis-factory.mapper-location-pattern}") String mapperLocations) {
  SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource());
  sqlSessionFactoryBean.setMapperLocations(findMapperLocations(mapperLocations));
  return sqlSessionFactoryBean;
}

private Resource[] findMapperLocations(String resourcePaths) {
  PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
  return Stream.of(resourcePaths.split(","))
      .map(LambdaExceptionUtilities.rethrowFunction(patternResolver::getResources))
      .flatMap(Stream::of)
      .toArray(Resource[]::new);
}

有财产

datasource.mybatis-factory.mapper-location-pattern=classpath*:sqlmap/*.xml

那么:这里缺少了什么东西来使它工作而没有周围的工作?类路径上的XML如何找到进入MyBatis的方法?也许是Spring-Bootish缺少的东西?

yi0zb3m4

yi0zb3m41#

我最近遇到了同样的问题。我相信这就是你要找的:

@Bean
@ConfigurationProperties("datasource.mybatis-factory")
public SqlSessionFactoryBean sqlSessionFactoryBean(
    @Value("${datasource.mybatis-factory.mapper-location-pattern}") String mapperLocations) {
  SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource());
  sqlSessionFactoryBean.setMapperLocations(
      new PathMatchingResourcePatternResolver().getResources("classpath*:sqlmap/*.xml")
  );
  return sqlSessionFactoryBean;
}

基本上,您需要的是上面@Bean定义中的这行代码:
sqlSessionFactoryBean.集合Map器位置(新路径匹配资源模式解析器().获取资源("类路径 :sqlmap/. xml") );
注意:方法名是getResources(复数),而不是getResource
您可以将classpath*:sqlmap/*.xml的硬编码值替换为@Value("datasource.mybatis-factory.mapper-location-pattern")注入值。
因为您在Spring中使用MyBatis,所以这里的问题与其说是MyBatis的问题,不如说是Spring的问题,更具体地说,您想要用来加载多个资源的通配符特性,即classpath*:sqlmap/*.xml,是Spring特有的,而不是MyBatis。
我知道,MyBatis-Spring文档中的记录方式可能会让你相信这是一个MyBatis特性,让你可以进行这种类型的通配符资源加载,但事实并非如此。https://mybatis.org/spring/factorybean.html#properties):
mapperLocations属性接受资源位置列表。此属性可用于指定MyBatis XMLMap程序文件的位置。此值可包含Ant样式模式,以加载目录中的所有文件或从基位置递归搜索所有路径。
然而,遗憾的是,文档只提供了一个基于XML的Spring示例,而没有提供Java配置。如果您阅读Java Docs的SqlSessionFactoryBean文档,您会发现以下内容(源代码:设置Map器位置(org.springframework.core.io.Resource...)):

public void setMapperLocations(org.springframework.core.io.Resource... mapperLocations)

Set locations of MyBatis mapper files that are going to be merged into the
SqlSessionFactory configuration at runtime.

This is an alternative to specifying "<sqlmapper>" entries in an MyBatis config file.
This property being based on Spring's resource abstraction also allows for
specifying resource patterns here: e.g. "classpath*:sqlmap/*-mapper.xml".

Parameters:
    mapperLocations - location of MyBatis mapper files

因此,setMapperLocations方法需要一个或多个org.springframework.core.io.Resource对象。因此,使用Spring ClassPathResource在这里不起作用,因为ClassPathResource只需要一个资源。您需要使用Spring的PathMatchingResourcePatternResolver类。请参见:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/support/PathMatchingResourcePatternResolver.html
你可能也会发现这篇堆栈溢出的帖子很有用:How to use wildcards when searching for resources in Java-based Spring configuration?
希望这能有所帮助!

wpcxdonn

wpcxdonn2#

你的属性应该是这样的.如果你使用默认配置,

mybatis.mapper-locations: classpath*:sqlmap/**/*.xml

如果您像上面提到那样使用自己的,

datasource.mybatis-factory.mapper-locations= classpath*:sqlmap/**/*.xml
emeijp43

emeijp433#

这是一个工作示例代码,你可以从中得到一些启发。

@Configuration
@MapperScans(
        {

                @MapperScan(
                        basePackages = {"com.example.seeker.repository"},
                        sqlSessionFactoryRef = "sqlSessionFactorySeeker",
                        sqlSessionTemplateRef = "sqlSessionTemplateSeeker"
                )
        }
)
public class SeekerDataSourceConfig {
    @Autowired
    Environment environment;

    @Bean(value = "dsSeeker")
    @ConfigurationProperties(prefix = "spring.datasource.seeker")
    DataSource dsSeeker() {
        return DataSourceBuilder.create().build();
    }

    @Qualifier("dsSeeker")
    @Autowired
    private DataSource dsSeeker;

    @Bean(value = "sqlSessionFactorySeeker")
    public SqlSessionFactory sqlSessionFactorySeeker() {
        SqlSessionFactory sessionFactory = null;
        try {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            PathMatchingResourcePatternResolver pathM3R = new PathMatchingResourcePatternResolver();
            bean.setMapperLocations(pathM3R.getResources("classpath*:sqlmap/**/*.xml"));
            bean.setDataSource(dsSeeker);
            sessionFactory = bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }

    @Bean(value = "sqlSessionTemplateSeeker")
    public SqlSessionTemplate sqlSessionTemplateSeeker() {
        return new SqlSessionTemplate(sqlSessionFactorySeeker());
    }

    @Bean(name = StaticResource.TxManager.TX_MANAGER_SEEKER)
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dsSeeker);
    }

}

属性档桉

spring.datasource.seeker.jdbc-url=jdbc:mysql://*********
spring.datasource.seeker.username=seeker***
spring.datasource.seeker.password=ewfky4eyrmggxbw6**
spring.datasource.seeker.driver-class-name=com.mysql.cj.jdbc.Driver
vkc1a9a2

vkc1a9a24#

如果你想使用yml文件,你可以在下面的路径中添加你的应用程序.yml文件

mybatis:
  mapperLocations: classpath:sql/*.xml
  config-location: classpath:config/mybatis.xml

相关问题