spring - डेटा स्रोत कनेक्शन url रनटाइम बदलना




hibernate datasource (2)

यदि आप कई डेटाबेस कनेक्शनों के लिए पूछ रहे हैं .. यह कई hibernate.cfg.file cfg.file बनाकर सीतनिद्रा में होना संभव है, जो कि कुछ अनुचित है

निम्नलिखित पंक्ति से आप इसे प्राप्त कर सकते हैं

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

जब आपका प्राथमिक कनेक्शन स्थापित नहीं हुआ है, तो आपको अन्य hibernate configuration लोड हो रहा है ... अन्यथा संभव नहीं है

मैं एक ऐसे प्रोजेक्ट पर काम कर रहा हूं जो कनेक्शन पूलिंग के लिए स्प्रिंग + हाइबरनेट + आईएसएसएलएल और सी 3 पी 0 का उपयोग करता है।

वर्तमान में कनेक्शन पूल के गुणों को स्रोत के बाहर परिभाषित गुणों के द्वारा लोड किया जाता है (उदाहरण: $ {db_uname})

जब हम स्प्रिंग बीन बनाते हैं तब सबकुछ ठीक शुरू होता है।

ऐसा हो सकता है कि जिस डेटाबेस से हमने कनेक्ट किया है वह किसी कारण के लिए दुर्गम है, और हम मेजबान को स्विच करना चाहते हैं।

कॉल वापस लागू करने की आवश्यकता है, जहां इसे नए होस्ट से कनेक्ट करना और पूल को पुन: प्रारंभ करना चाहिए

मौजूदा डेटा स्रोत / कनेक्शन पूल को ईर्ष्या से कैसे ओवरराइड करने के लिए कोई भी संकेतक बहुत मददगार होगा।

यहाँ मेरा स्प्रिंग कॉन्फ़िग फ़ाइल कैसा दिखता है

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<!-- Component scans -->
<import resource="component-scans-1.xml" />
<import resource="component-scans-2.xml" />


<util:properties id="serviceManagerProperties" 
    location="classpath:servicemanagers.properties" />

<!-- Properties file -->
<context:property-placeholder location="classpath:database.config.properties,classpath:framework.properties" />

<!-- context:annotation-config / -->
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<context:mbean-server id="mbeanServer" />
<context:mbean-export server="mbeanServer" default-domain="a.b.c" />

<bean id="cacheManager" factory-method="getInstance"
    class="net.sf.ehcache.CacheManager" />

<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
    <constructor-arg ref="cacheManager" />
    <constructor-arg ref="mbeanServer" />
    <constructor-arg value="false" />
    <constructor-arg value="false" />
    <constructor-arg value="false" />
    <constructor-arg value="true" />
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaAdapter" />
    <property name="persistenceXmlLocation" value="classpath*:META-INF/framework-persistence.xml" />
    <property name="persistenceUnitName" value="PU-NAME" />
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
            <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
            <prop key="hibernate.cache.region.factory_class">
                org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
            </prop>

            <prop key="hibernate.ejb.cfgfile">hibernate.cfg.xml</prop>
            <prop key="hibernate.generate_statistics">true</prop>


            <!-- CONNECTION SETTINGS -->
            <prop key="hibernate.connection.driver_class">
                com.mysql.jdbc.Driver
            </prop>
            <prop key="hibernate.connection.url">
                jdbc:mysql://${dbhost}/${dbschema}?zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;characterEncoding=UTF-8
            </prop>
            <prop key="hibernate.connection.username">${dbuser}</prop>
            <prop key="hibernate.connection.password">${dbpass}</prop>

            <!-- CONNECTION POOLING -->
            <prop key="hibernate.connection.provider_class">
                org.hibernate.connection.C3P0ConnectionProvider
            </prop>
            <prop key="hibernate.c3p0.maxPoolSize">${hibernate.c3p0.maxSize}</prop>
            <prop key="hibernate.c3p0.minPoolSize">${hibernate.c3p0.minSize}</prop>
            <prop key="hibernate.c3p0.acquireIncrement">${hibernate.c3p0.acquireIncrement}</prop>
            <prop key="hibernate.c3p0.idleConnectionTestPeriod">${hibernate.c3p0.idleTestPeriod}</prop>
            <prop key="hibernate.c3p0.maxStatements">${hibernate.c3p0.maxStatements}</prop>
            <prop key="hibernate.c3p0.timeout">${hibernate.c3p0.timeout}</prop>

        </props>
    </property>
</bean>

<bean id="jpaAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

डाटाबेस स्कीमा को मानते हुए सही है, कहने पर कि मैं डेटाबेस क्रेडेंशियल्स और घटना की मेजबानी जानकारी प्राप्त करता हूं, मुझे कनेक्शन पूल को फिर से सेट करना होगा।


अब्बरराउटिंगडेटासोर्स एक अच्छा विकल्प है।

एक्सएमएल या एनोटेशन इस तरह प्रयोग किया जाता है:

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

फिर वर्तमान डेटासेट को निर्धारित करने के लिए एक क्लास बनाएं।

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

}

वैसे, 'try-end' कथन उबाऊ है!

try{
    RoutingDataSource.setDataSourceKey("ds1");
    myDao.doXXX();
}finally{
    RoutingDataSource.clear();
}