我现在遇到的问题是我一直在做很多搜索,但仍然没有找到答案。
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'
任何建议都将不胜感激!
答案 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重用。