#jndi #c3p0 #mybatis
#jndi #c3p0 #mybatis
Вопрос:
У меня есть 2 отдельных подключения к данным, которые мне нужно обрабатывать в течение жизненного цикла приложения j2ee. Все его свойства известны заранее, и я настраиваю 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’s 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);
Видите ли, я пытаюсь передать имя пользователя и пароль в качестве объекта Property, когда получаю свой SqlSessionFactory. Когда я просматриваю свои сообщения журнала в tomcat для c3p0, я вижу, что свойства c3p0 пусты, и, по-видимому, он никогда не слышал от MyBatis, каковы имя пользователя и пароль, поэтому он не может установить соединение. Я знаю, что использую правильную «пользовательскую» среду, просто как мне правильно установить имя пользователя и пароль для этого соединения? Спасибо за вашу помощь.
Ответ №1:
Хорошо, я выяснил все, что мне нужно сделать, поэтому позвольте мне поделиться.
Я нашел этот лакомый кусочек где-то в списке рассылки 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);
Какое разочарование! Я должен знать, какой источник данных я использую. Это как бы уменьшает некоторые реальные возможности MyBatis. В любом случае, здесь я знаю, какое имя пользователя следует выбрать, поэтому я установил свойство User для этого конкретного источника данных c3p0, и теперь я могу открывать сеансы с 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>
Итак, здесь я не указал свойство user, которое должно задаваться динамически, как я только что продемонстрировал. Вот и все, MyBatis интегрирован с c3p0. Я думаю, это демонстрирует слабость MyBatis в том, что вам приходится глубоко копаться в объекте SqlSessionFactory. Но опять же, если я выбираю фреймворк, я нереалистично ожидаю волшебства. И с MyBatis я не получаю волшебства. В противном случае, есть другие варианты, которые могут быть сделаны для обработки сохранения.
Комментарии:
1. Именно то, что я искал!