Pregunta

Tengo 2 conexiones de datos separadas que necesito manejar durante el ciclo de vida de una aplicación J2EE. Uno tiene todas sus propiedades conocidas de antemano y configuro mybatis como así

    <environment id="development">
        <transactionManager type="JDBC" />
        <dataSource type="JNDI">
            <property name="data_source" value="java:comp/env/jdbc/pooledDS" />
        </dataSource>
    </environment>

Esto es genial. Pooledds se refiere a mi fuente de datos configurada C3P0. La segunda conexión se creará con un combo de nombre de usuario/contraseña que se determina cuando un usuario inicia sesión en la aplicación. Me gustaría usar C3P0 nuevamente para esa fuente de datos e intento configurar mybatis.xml como

    <environment id="user">
        <transactionManager type="JDBC" />
        <dataSource type="JNDI">
            <property name="data_source" value="java:comp/env/jdbc/pooledDS2" />
        </dataSource>
    </environment>

Mi entrada de recursos correspondiente en el contexto de mi Tomcat.xml es

   <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" /> 

Verá, dejo los atributos del usuario y la contraseña en blanco porque no los conozco. Cuando conozco al usuario para quien necesito una conexión, intento lo siguiente:

        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);

Verá, trato de pasar el nombre de usuario y la contraseña como un objeto de propiedad cuando obtengo mi SQLSessionFactory. Cuando miro mis mensajes de registro en Tomcat para C3P0, veo que las propiedades C3P0 están vacías y aparentemente nunca escuchó de MyBatis cuáles son los nombre de usuario y la contraseña para que no pueda hacer una conexión. Sé que estoy usando el entorno correcto "Usuario", es cómo configuro correctamente el nombre de usuario y la contraseña para esta conexión. Gracias por tu ayuda.

¿Fue útil?

Solución

Ok, descubrí todo lo que necesito hacer, así que déjame compartir.

Encontré este dato en algún lugar u otro en la lista de correo de 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); 
    }

Sin embargo, mucho mi disgusto, no puedo transmitir mis propias propiedades como estaba tratando de hacerlo. Las únicas propiedades que aparecen en el método SetProperties anterior son aquellas que se definen en el archivo mybatis.xml, qué decepcionante.

Luego ajustamos la llamada para construir de la siguiente manera:

            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);

¡Que decepcionante! Tengo que saber qué tipo de fuente de datos estoy usando. Eso reduce parte de la verdadera carne de mybatis. De todos modos, aquí sé qué nombre de usuario se seleccionará, así que configuré la propiedad de usuario de esa fuente de datos C3P0 en particular y ahora puedo abrir sesiones con MyBatis como de costumbre.

Finalmente, ¿cómo se ve el entorno del "usuario"? ¿Qué tal esto?

        <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>

Así que aquí he dejado de lado la propiedad del usuario para que se establezca dinámicamente como acabo de demostrar. Eso es todo, MyBatis se integró con C3P0. Creo que esto demuestra una debilidad de mybatis que tienes que profundizar en el objeto SQLSessionFactory. Pero, de nuevo, si elijo un marco, estoy esperando la magia de manera poco realista. Y con mybatis no obtengo magia. De lo contrario, hay otras opciones que se pueden hacer para manejar la persistencia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top