How to set database login information from variable?
Question
I am using MyBatis in a Java project. I know that database access information such as host, database name, username and password are stored in configuration.xml
. But I would like to know if I can set these login information from inside my Java program.
It's because my application is accessing different databases on different addresses and I am configuring them in the application. Please help me.
Solution
The configuration xml file supports a <properties>
element. You can either point to an external file (through the resource
attribute) or define each <property>
directly in the xml.
Properties can be referenced elsewhere in the Mybatis config and mapper xml files with ${property}
syntax like this (from the documentation):
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
Note that property elements override any properties defined in the file.
OTHER TIPS
Because the existing answers were not enough to help me out with the same problem, here is my solution. It works with myBatis 3.2.1.
1. In mybatis-config.xml
- Add those property elements you want to set from inside Java to the
<property>
section. - Refer to those elements in the
<dataSource>
section using${*property*}
as value.
<?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>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
...
</mappers>
</configuration>
2. In Java
Create a Properties
object, add the properties you selected to set manually and pass it to the build()
method when obtaining the SqlSessionFactory
:
Properties properties = new Properties();
properties.setProperty("username", "myUser");
properties.setProperty("password", "myPwd");
properties.setProperty("url", "myConnectionURL");
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, properties);
Because the existing answers were not enough to help me out with the same problem, here is my solution. It works with myBatis 3.0.3.
mybatis-config.xml file:
<?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>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
...
</mappers>
</configuration>
Java Code:
Properties properties = new Properties();
properties.setProperty("username", userName);
properties.setProperty("password", password);
properties.setProperty("url", dbURL);
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, properties);
Note: For myBatis 3.0.3, SqlSessionFactoryBuilder().build() method does not take InputStream as a parameter as suggested in answer by user905686, you should use the Reader instead.
If you want to do using Spring 4 and @Configuration in Data Config
How to set fetchSize for iBatis select statement
The difference is the way you can load config file
@Value("classpath:mybatis-config.xml")
private Resource myBatisResource ;
Write yourself datasource which extends form BasicDataSource, as follows.
package org.popkit.mydatasource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
public class MyDataSource extends BasicDataSource implements InitializingBean {
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public void afterPropertiesSet() throws Exception {
String url = this.getUrl();
// following do as yourself
if (StringUtils.isBlank(url)) {
this.setUrl("#your jdbc.url");
}
String username = this.getUsername();
if (StringUtils.isBlank(username)) {
this.setUsername("#your jdbc.username");
}
String password = this.getPassword();
if (StringUtils.isBlank(password)) {
this.setPassword("#your jdbc.pwd");
}
}
}
in xml
<bean id="dataSource" class="org.popkit.mydatasource.MyDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value=""/>
<property name="username" value="" />
<property name="password" value=""/>
<property name="initialSize" value="2" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="10" />
<property name="minIdle" value="3" />
<property name="maxWait" value="30000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="30" />
<property name="validationQuery" value="SELECT 1" />
</bean>
First write the information regarding driver,username,password in some file and read that file contents in your java application
Properties properties=new Properties();
properties.load("INPUTSTREAM");