从属性文件中获取模式名称

时间:2012-03-23 14:58:47

标签: spring ibatis mybatis

我现在遇到的问题是我一直在做很多搜索,但仍然没有找到答案。

Backgorund of problem:我们在一个URL上有多个数据库模式,包括模式的测试副本(例如schema1,schema2,schema1_test,schema2_test都在同一个url中)。我正在尝试使用属性文件来配置每个模式的哪个版本。

我们正在使用Spring和mybatis,不幸的是我对两者都不熟悉(所以请原谅我的无知或我描述问题的任何错误!)


所以在我的spring配置文件中,存储在/ src / main / resources下,我有以下片段: (我只添加了“configLocation”属性,后来添加了“sqlSessionFactoryBeanName”属性)

<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="typeAliasesPackage" value="com.example.domain" />
    <property name="configLocation" value="classpath:mybatisConfig.xml" />
</bean>

<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.something.persistence" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>


我的mybatisConfig.xml(存储在/ src / main / resources下,应该在类路径上)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="sqlmapconfig.properties" />
</configuration>


sqlmapconfig.properties(在同一文件夹中)

schema1=schema1_test


我尝试在com.example.something.persistence:

中的一个映射器文件中引用该属性
 <select id="test" resultType="result" parameterType="long">
    select ${schema1}.table.col  
    from ${schema1}.table 
 </select>

当我尝试使用maven构建时,它无法通过测试:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'schema1' in 'class java.lang.Long'

任何建议都将不胜感激!

2 个答案:

答案 0 :(得分:4)

我放弃了尝试直接读取属性并将其从Java路径传递下来

所以我不得不将“parameterType”更改为mapper文件中的地图

<select id="test" resultType="result" parameterType="map">
    select ${schema1}.table.col  
    from ${schema1}.table where number=#{number}
</select>

编辑java mapper代码如下

import org.apache.ibatis.annotations.Param;

...

public List<result> test(@Param("number") long number, @Param("schema1") String schema1);

希望这有助于某人。

Notes&amp;参考文献:

谨慎使用$ {} vs#{},差异解释here

如何使用来自here

的多个参数

答案 1 :(得分:0)

我遇到了类似问题,并设法通过创建自定义LanguageDriver来实现此目的。 mybatis中的语言驱动程序有很少的钩子方法。有趣的是createSqlSource,在加载每个定义的sql语句时调用它。这允许您在此时修改语句。执行此操作的最佳方法是扩展XMLLanguageDriver,它是解释xml文件和注释中定义的查询的默认驱动程序。

首先要做的是通过添加一些标记来修改您的查询,该标记将替换为模式(SCHEMA_MARKER是从自定义语言驱动程序类导入的,如下所示):

public interface MyMabatisMapper {
  @Select("select * from " + SCHEMA_MARKER + ".myTable ")
  List<MyObjects> getObjects();
}

现在我们创建自定义语言驱动程序,它将用给定的模式替换标记。

示例:

public class QueriesModifyingDriver extends XMLLanguageDriver {

  public static final String SCHEMA_MARKER = "###MY_SCHEMA###";
  public static final String SCHEMA_MARKER_PATTERN = SCHEMA.replaceAll("#", "\\#");

  private final String schemaName;

  // NOTE: Name of the schema passed in constructor !!!
  public QueriesModifyingDriver(String schemaName) {
    this.schemaName = schemaName;
  }

  @Override
  public SqlSource createSqlSource(org.apache.ibatis.session.Configuration configuration, String script, Class<?> parameterType) { 
    String modifiedScript = script.replaceAll(SCHEMA_MARKER_PATTERN, schemaName);

    return super.createSqlSource(configuration, modifiedScript, parameterType);
  }
};

上面我们通过构造函数将模式的名称传递给我们的语言驱动程序。现在我们需要做的就是将这个语言驱动程序安装到mybatis。下面的示例假定使用注释配置使用Spring。模式名称是从属性my.schema.name中读取的,但它可以从任何来源获得:

  @Bean
  public SqlSessionFactory mybatisSqlSessionFactory(DataSource dataSource, @Value("${my.schema.name}") String schemaName) throws Exception {

    SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    sqlSessionFactoryBean.setDataSource(dataSource);

    org.apache.ibatis.session.Configuration mybatisConfiguration = sqlSessionFactoryBean.getObject().getConfiguration();

    QueriesModifyingDriver queriesModifyingDriver = new QueriesModifyingDriver(schemaName);
    mybatisConfiguration.getLanguageRegistry().register(queriesModifyingDriver);

    mybatisConfiguration.setDefaultScriptingLanguage(QueriesModifyingDriver.class);

    return sqlSessionFactoryBean.getObject();
  }

请注意,这是非常有效的方法,因为语言驱动程序只会处理每个查询一次(在启动时),并且此修改后的查询稍后会被mybatis重用。