First the problem: I'm using XML-defined queries and the SQL contains database name as part of a table name. For example: SELECT * from mydb.bar
. Unfortunately, databases are created/named all over the place and mudb
part is really dynamic and can change at any moment. So I wanted to replace it with a property so it would look like SELECT * FROM ${dbname}.bar
and then I defined the following section in mybatis-config.xml:
<properties>
<property name="dbname" value="mydb"/>
</properties>
But when I run the query ${dbname}
evaluates to null. Same happens if I define this property in the properties file. I would hate to pass this as part of the each call parameters since this is truly a global property. Can this be done? And if yes - how?
Yes, you can! This is kind of a weird undocumented feature maybe. When building your Configuration object, do something like this. (org.apache.ibatis.session.Configuration)
configuration.getVariables().put("global_param", "123");
Then in your XML map, you can reference.
select * from ${global_param}
I had the same issue using Spring+MyBatis, and solved it by setting 'configurationProperties' using my Spring XML definition for sqlSessionFactory. My example below shows how to set a custom global property named 'encryptionKey', with a value which you can either hard-code in the XML file, or load from an external file using the context:property-placeholder tag (as below).
<context:property-placeholder location="/WEB-INF/spring/config-datasource.properties" />
<beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="typeAliasesPackage" value="com.example.model" />
<beans:property name="configurationProperties">
<beans:props>
<beans:prop key="encryptionKey">${jdbc.encryptionKey}</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
I was using an XML configuration but not Spring and set a property inside the Configuration object but discovered that had to be done before the mapper files are loaded (see here). I abandoned the Configuration object approach and went with this approach, which worked for me:
Reader reader = Resources.getResourceAsReader("..../mybatis-config.xml");
Properties properties = new Properties();
properties.setProperty("dbname", "mydb");
SqlSessionFactory.factory = new SqlSessionFactoryBuilder().build(reader, "development", properties);
Then, as Andy Pryor posted, use select * from ${dbname}
in the XML mapper.