Changing datasource connection url runtime

前端 未结 3 1524
生来不讨喜
生来不讨喜 2020-12-14 13:30

I am working on a project which uses spring + hibernate + mysql and c3p0 for connection pooling.

Currently the properties for the connection pool are loaded via prop

相关标签:
3条回答
  • 2020-12-14 14:15
    <beans:bean id="dataSource"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <beans:property name="targetSource" ref="swappableDataSource" />
    </beans:bean>
    
    <beans:bean id="dummyDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close" />
    
    <beans:bean name="swappableDataSource"
        class="org.springframework.aop.target.HotSwappableTargetSource">
        <beans:constructor-arg ref="dummyDataSource" />
    </beans:bean>
    

    and some where in your code you can do this.

    @Autowired
    HotSwappableTargetSource swapable;
    
    public void changeDatasource() throws Exception
    {
                swapable.swap(createNewSource();
    
    }
    
    
    ComboPooledDataSource createNewSource() throws Exception {
        ComboPooledDataSource ds2 = new ComboPooledDataSource();
        ds2.setJdbcUrl(url);
        ds2.setDriverClass(driver);
        ds2.setUser(username);
        ds2.setPassword(password);
    
    
        return ds2;
    }
    
    0 讨论(0)
  • 2020-12-14 14:28

    AbstractRoutingDataSource is a good choice.

    Xml or annotation used like this:

    <bean id="ds1" class="..c3p0.DataSource">
        ...
    </bean>
    
    <bean id="ds2" class="..c3p0.DataSource">
        ...
    </bean>
    
    <bean id="dataSource" class="..xxx.RoutingDataSource">
       <property name="targetDataSources">
          <map key-type="java.lang.String">
             <entry key="ds1" value-ref="ds1"/>
             <entry key="ds2" value-ref="ds2"/>             
          </map>
       </property>
       <property name="defaultTargetDataSource" ref="ds1"/>
    </bean>
    
    
    
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" /> 
    ...
    </bean>
    

    Then build a class to determine current datasoruce.

    public class RoutingDataSource extends AbstractRoutingDataSource {
        private static final ThreadLocal<String> holder = new ThreadLocal<String>();
    
        protected Object determineCurrentLookupKey()
        {
            return holder.get();
        }
    
        public static void clear(){
            holder.remove();
        }
    
        public static void setDataSourceKey(String key){
            holder.set(key);
        }
    
    }
    

    By the way, the 'try-finally' statement is boring!

    try{
        RoutingDataSource.setDataSourceKey("ds1");
        myDao.doXXX();
    }finally{
        RoutingDataSource.clear();
    }
    
    0 讨论(0)
  • 2020-12-14 14:29

    If you are asking for multiple databases connections ..it is possible with hibernate by creating multiple hibernate.cfg.file 's which is some what inappropriate

    By following line you can acheive that .

    SessionFactory sf = new Configuration().configure("somename.cfg.xml").buildSessionFactory();
    

    When your primary connection not established you have load another hibernate configuration ...otherwise is wont possible .

    0 讨论(0)
提交回复
热议问题