动态(运行时)更改Spring Mybatis中的数据源凭据

时间:2014-02-07 22:52:20

标签: spring jdbc datasource mybatis

我想在Spring + MyBatis项目中动态更改数据源属性。

问题出在Spring + MyBatis集成中,我们无法在运行时动态设置数据源属性。

目前我正在使用以下代码设置凭据:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.url}" p:username="${jdbc.username}"
    p:password="${jdbc.password}" />

我尝试使用UserCredentialsDataSourceAdapter选项在运行时更改密码,但我无法返回用作连接的dataSource对象,如MyBatis

ApplicationContext context = ApplicationContextUtils.getApplicationContext();
UserCredentialsDataSourceAdapter ds = (UserCredentialsDataSourceAdapter) context.getBean("dataSource");
ds.setCredentialsForCurrentThread("test", "test");

我被困在这里,我不能使用dataSource元素ds来为MyBatis建立连接。请帮我解决这个问题。

3 个答案:

答案 0 :(得分:4)

我想您使用mybatis-spring

您使用UserCredentialsDataSourceAdapter的方法无效,因为您正在使用连接池,因此连接在使用后不会关闭,但会返回到池中并在以后重新使用,即使您已更改用户名和密码。 解决这个问题就是摆脱游泳池:

<bean id="targetDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
  <property name="targetDataSource" ref="targetDataSource"/>
  <property name="username" value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</bean>

并在SqlSessionFactoryBean配置中使用后面的bean:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

如果你不使用mybatis-spring并直接使用mybatis,那么问题是让mybatis使用配置的DataSource。这可以通过JNDI中的registering dataSource和configure mybatis来完成,以从JNDI获取DataSource。

答案 1 :(得分:0)

    

<bean id="targetDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${app.jdbc.driverClassName}" />
    <property name="url" value="${app.jdbc.url}" />
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
    <property name="targetDataSource" ref="targetDataSource" />
    <property name="username" value="#{app.jdbc.username}" />
    <property name="password" value="#{app.jdbc.password}" />
</bean>

<!-- Declare a transaction manager for Encounter Navigator Authenticator -->
<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- define the SqlSessionFactory for Encounter Navigator Authenticator, 
    notice that configLocation is not needed when you use MapperFactoryBean -->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
    name="sqlSessionFactory">
    <property name="dataSource" ref="dataSource" />
    <property name="mapperLocations"
        value="file:C:/Program Files/Apache Software Foundation/Tomcat 7.0/config/app_user/*.xml" />
    <property name="configLocation" value="classpath:sqlmap-config.xml" />
</bean>

<!-- scan for MAPPERS and let them be auto-wired - For Encounter Navigator 
    Authenticator -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage"
        value="com.upmc.health.encounternavigator.dao.authentication" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

答案 2 :(得分:0)

UserCredentialsDataSourceAdapter ds = (UserCredentialsDataSourceAdapter) applicationContext.getBean("dataSource");
ds.removeCredentialsFromCurrentThread();
ds.setCredentialsForCurrentThread("test", "test");
ds.setUsername("test");
ds.setPassword("test");
ds.setTargetDataSource(ds);
ds.afterPropertiesSet();

authDao.getDetails(); //这会调用一个接口并执行xml文件中的查询