我需要在j2ee应用程序的生命周期中处理2个独立的数据连接。一个人事先知道它的所有属性,我将myBatis配置为
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/pooledDS" />
</dataSource>
</environment>
这很棒。 PooledDS指的是我的c3p0配置数据源。将使用用户名/密码组合创建第二个连接,该用户名/密码组合是在用户登录到应用程序时确定的。我想再次使用c3p0作为该数据源,我尝试将mybatis.xml配置为
<environment id="user">
<transactionManager type="JDBC" />
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/pooledDS2" />
</dataSource>
</environment>
我在Tomcat的context.xml中的相应资源条目是
<Resource name="jdbc/pooledDS2" auth="Container"
description="DB Connection for Users"
driverClass="oracle.jdbc.driver.OracleDriver"
maxPoolSize="100" minPoolSize="10" acquireIncrement="1"
factory="org.apache.naming.factory.BeanFactory"
maxIdleTime="850"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
jdbcUrl="jdbc:oracle:thin:@localhost:1521:orcl4" />
您看,我将用户和密码属性留空,因为我不知道它们。当我知道需要连接的用户时,我会尝试以下操作:
Reader reader = Resources.getResourceAsReader(RESOURCE);
Properties userProps = new Properties();
userProps.setProperty("user", loginName);
userProps.setProperty("username", loginName);
userProps.setProperty("password", password);
sqlMapperUser = new SqlSessionFactoryBuilder().build(reader, "user", userProps);
你知道,当我得到我的SqlSessionFactory时,我尝试将用户名和密码作为Property对象传递。当我在tomcat中查看c3p0中的日志消息时,我看到c3p0属性为空,显然它从来没有从myBatis中听到用户名和密码是什么,因此它无法建立连接。我知道我正在使用正确的“用户”环境,这是如何正确设置此连接的用户名和密码?谢谢你的帮助。
答案 0 :(得分:3)
好的,我想出了我需要做的一切,让我分享。
我在mybatis google邮件列表中找到了这个或那个地方的这个花絮:
import java.beans.PropertyVetoException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.datasource.DataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0DataSourceFactory implements DataSourceFactory {
private ComboPooledDataSource dataSource = null;
public C3P0DataSourceFactory () {
}
public void setProperties(Properties properties) {
this.dataSource = new ComboPooledDataSource();
this.dataSource.setPassword(properties.getProperty("password"));
this.dataSource.setJdbcUrl(properties.getProperty("url"));
try {
this.dataSource.setDriverClass(properties.getProperty("driver"));
} catch (PropertyVetoException e) {
}
}
public DataSource getDataSource() {
return (this.dataSource);
}
虽然我很懊恼,但我不能像我想要的那样传递自己的属性。上面的setProperties方法中出现的唯一属性是mybatis.xml文件中定义的属性,令人失望。
然后我们按如下方式调整构建调用:
Reader reader = Resources.getResourceAsReader(RESOURCE);
Properties userProps = new Properties();
sqlMapperUser = new SqlSessionFactoryBuilder().build(reader, "user");
ComboPooledDataSource ds = (ComboPooledDataSource) sqlMapperUser.getConfiguration().getEnvironment().getDataSource();
ds.setUser(loginName);
多么令人失望!我必须知道我正在使用什么样的DataSource。这种方式减少了MyBatis的一些真正的肉。无论如何,在这里我知道要选择哪个用户名,所以我设置了特定c3p0数据源的User属性,现在我可以像往常一样用mybatis打开会话。
最后,“用户”环境是什么样的?怎么样?
<environment id="user">
<transactionManager type="JDBC" />
<dataSource type="C3P0DataSourceFactory">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl4" />
<property name="password" value="snotty" />
</dataSource>
</environment>
所以这里我省略了动态设置的用户属性,就像我刚才演示的那样。就是这样,MyBatis与c3p0集成在一起。我认为这证明了MyBatis的一个弱点,你必须深入研究SqlSessionFactory对象。但话说回来,如果我选择一个框架,我会不切实际地期待魔法。而使用MyBatis,我不会得到魔法。否则,还有其他选择可以处理持久性。