iBatis - select environment using XML
I have this configuration in ibatis-config.xml
<configuration>
<properties resource="collector.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${dev.jdbc.driver}" />
<property name="url" value="${dev.jdbc.url}" />
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${test.jdbc.driver}" />
<property name="url" value="${test.jdbc.url}" />
</dataSource>
</environment>
</environments>
<mappers>
</mappers>
</configuration>
As shown it will load datasource from <environment id="development">
QUESTION: Is it poss开发者_运维百科ible at run time switch to use <environment id="test">
without modifying XML? For example - I have a test file where I'm using SqlSessionFactory
and want to set it programmatically to use test environment?
SqlSessionFactoryBuilder.build() method can select a specific environment in XML.
For example,
private Reader reader;
private SqlSessionFactory sqlSessionFactorys;
private SqlSession session;
reader = Resources.getResourceAsReader("ibatis-config.xml");
sqlSessionFactorys = new SqlSessionFactoryBuilder().build(reader, "test");
testSession = sqlSessionFactorys.openSession(); // test env
sqlSessionFactorys = new SqlSessionFactoryBuilder().build(reader, "development");
devSession = sqlSessionFactorys.openSession(); // dev env
According to this site: http://codenav.org/code.html?project=/org/mybatis/mybatis/3.2.5&path=/Source%20Packages/org.apache.ibatis.session/SqlSessionFactoryBuilder.java
The build()
method closes the reader/inputstream before returning SqlSessionFactory now. So you will need to open a new reader/stream in order to load the second session. I discovered this when I separated out my account/security tables to a separate database from the main application DB. My first go around I kept getting errors when the bean was trying to load the session factory due to an input stream error (closed).
e.g.
try {
inputStream = Resources.getResourceAsStream(MYBATIS_CONFIG_PATH);
prodDbSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, prodDbEnvironment);
inputStream = Resources.getResourceAsStream(MYBATIS_CONFIG_PATH);
securityDbSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, securityDbEnvironment);
} catch (IOException ex) {
String msg = "Unable to get SqlSessionFactory";
CustomizedLogger.LOG(Level.SEVERE, this.getClass().getCanonicalName(), "methodName", msg, ex);
}
Although I put them in separate try catch blocks so that I know which one failed specifically right away in the log file.
I also implement this as a singleton so that it only has to load load resources once.
Context: I run this in a Java EE container and use MyBatis for straight forward queries and for where I would use native queries since it is a much simpler and straight forward framework. I might switch to using it over JPA everywhere, but that is still up for debate.
精彩评论