A. 多數據源
根據你的需求,貌似兩個庫之間的數據是邏輯分離的,就是說A庫用於項目的A模塊,B庫用於項目的B模塊,沒有交叉(或很少)。
如果是我,
我會在spring中建立兩個dataSource,建立兩個HibernateTemplate(就是說兩套隔離的資料庫訪問機制)
然後根據不同的業務需求為你的DAO類分別注入兩個、或其中一個HibernateTemplate
能夠實現你的需求,如果我看懂了你的問題的話:)
===============================================
關於事務的補充:
事務回滾能夠取消已經提交給資料庫的修改。但是,你現在的資料庫是分布式的,所以傳統的事務管理方式在此不能使用,應使用分布式的事務管理。也就是常說的JTA。
我記得你的項目架構是Spring+Hibernate,如果你不做配置,Spring的事務管理是無法解決你的問題,建議你使用Spring + JOTM來實現JTA。
JOTM 是一個基於Java開放源代碼的事務處理管理器。它遵循JTA APIs規范與Business Transaction Protocol(BTP)規范以提供了對Web Service的支持。
下面是幾個Struts+Spring+Hibernate+JOTM的配置文件案例,由於篇幅較長,就不直接貼了,希望對你有用。
你網路一下「Spring JOTM」太多內容了,估計夠了。
B. 一個java web項目可以鏈接多個庫嗎
當然可以連接多個資料庫,只不過你要連接的資料庫中要有設計的這些表,數據。
然後在項目改一下資料庫的埠號,加驅動,就行
C. java web導出excel 數據源問題
第一,頁面點擊導出按鈕,調用java後台查詢數據。
第二,將查詢出數據,進行Excel文件的寫入。
第三,成功,頁面提示導出成功。 失敗,提示導出失敗。
就這么簡單,樓主不要想的太復雜了。
D. java程序員在面試中被問到如何配置多數據源以及如何配置多數據源下的分布式事務,該怎麼回答看清再做答
你好,我來先回答你的第一個問題:
通常多數據源,在spring中配置如下,如果你想切換環境ENV 的值,在property中
<bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"></property>
<property name="" value="true"></property>
<property name="nullValue" value="NULL"></property>
<property name="locations">
<list>
<value>jdbc.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="com.spring..JDBCConfig">
<property name="driverClassName" value="${${Env}.jdbc.driverClassName}"></property>
<property name="url" value="${${Env}.jdbc.url}"></property>
<property name="username" value="${${Env}.jdbc.username1}"></property>
<property name="password" value="${${Env}.jdbc.password}"></property>
</bean>
jdbc.properties
*****************************
Env=PROD
jdbc.driverClassName=${${Env}.jdbc.driverClassName}
jdbc.url=${${Env}.jdbc.url}
jdbc.username=${${Env}.jdbc.username}
jdbc.password=${${Env}.jdbc.password}
######### JDBC Configuration for DEV Environment ###############
DEV.jdbc.driverClassName=com.mysql.jdbc.Driver
DEV.jdbc.url=jdbc:mysql://localhost:3306/devportal
DEV.jdbc.username=DEVuser
DEV.jdbc.password=DEVpwd
######### JDBC Configuration for UAT Environment ############
UAT.jdbc.driverClassName=com.mysql.jdbc.Driver
UAT.jdbc.url=jdbc:mysql://localhost:3306/UATportal
UAT.jdbc.username=UATuser
UAT.jdbc.password=UATpwd
########## JDBC Configuration for PROD Environment ############
PROD.jdbc.driverClassName=com.mysql.jdbc.Driver
PROD.jdbc.url=jdbc:mysql://localhost:3306/portal
PROD.jdbc.username=root
PROD.jdbc.password=admin,
我這里有三套環境,分別是DEV,UAT和PROD,這種方式可以靈活切換的。
我再回答你的第二個問題:
還請你去http://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/transaction.html這里看下,很詳細,不過是英文的哦
E. 在java web應用程序中,使用哪個數據源與jdbc獲得資料庫
對於數據源的應用,一般都選擇實用開源的數據源或資料庫連接池來使用,比如,常見的有DBCP、C3P0、Proxool等等。
對於jdbc的話,可以用mysql/mysql driver來實現。
F. Java web點擊按鈕切換數據源
如果要在Javaweb切換數據源,首先你需要新建數據源常量類,此類中的常量是通過spring-db.xml映射對應的,然後配置spring-db.xml,這個是spring鏈接資料庫的配置文件,再進行動態數據源設置,這個類是用來切換數據源,再獲取jdbcTemplate的管理類。最後測試動態數據源,一般會用Junit4做單元測試。
總結:這種切換比較規范和簡單,麻煩的是必須先配置多個數據源,以前是參考網上資料,自己修改的,希望對你有參考作用!
G. 如何在spring框架中解決多數據源的問題
在 我們的項目中遇到這樣一個問題:我們的項目需要連接多個資料庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫。我們以往 在 spring 和 hibernate 框架中總是配置一個數據源,因而 sessionFactory 的dataSource 屬性總是指向這個 數據源並且恆定不變,所有 DAO 在使用 sessionFactory 的時候都是通過這個數據源訪問資料庫。但是現在,由於項目的需要,我們 的 DAO 在訪問 sessionFactory 的時候都不得不在多個數據源中不斷切換,問題就出現了:如何讓 sessionFactory 在執 行數據持久化的時候,根據客戶的需求能夠動態切換不同的數據源?我們能不能在 spring 的框架下通過少量修改得到解決?是否有什麼設計模式可以利用 呢?
問題的分析
我 首先想到在 spring 的 applicationContext 中配置所有的 dataSource 。這些 dataSource 可能是各種 不同類型的,比如不同的資料庫: Oracle 、 SQL Server 、 MySQL 等,也可能是不同的數據源:比如 apache 提供的 org.apache.commons.dbcp.BasicDataSource 、 spring 提供的 org.springframework.jndi.JndiObjectFactoryBean 等。然後 sessionFactory 根據客戶的 每次請求,將dataSource 屬性設置成不同的數據源,以到達切換數據源的目的。
但 是,我很快發現一個問題:當多用戶同時並發訪問資料庫的時候會出現資源爭用的問題。這都是「單例模式」惹的禍。眾所周知,我們在使用 spring 框架 的時候,在 beanFactory 中注冊的 bean 基本上都是採用單例模式,即 spring 在啟動的時候,這些 bean 就裝載到內存中, 並且每個 bean 在整個項目中只存在一個對象。正因為只存在一個對象,對象的所有屬性,更准確說是實例變數,表現得就如同是個靜態變數(實際上「靜 態」與「單例」往往是非常相似的兩個東西,我們常常用「靜態」來實現「單例」)。拿我們的問題來說, sessionFactory 在整個項目中只有一 個對象,它的實例變數 dataSource 也就只有一個,就如同一個靜態變數一般。如果不同的用戶都不斷地去修改 dataSource 的值,必然 會出現多用戶爭用一個變數的問題,對系統產生隱患。
通過以上的分析,解決多數據源訪問問題的關鍵,就集中在 sessionFactory 在執行數據持久化的時候,能夠通過某段代碼去根據客戶的需要動態切換數據源,並解決資源爭用的問題。
問題的解決
(一) 採用 Decorator 設計模式
要 解決這個問題,我的思路鎖定在了這個 dataSource 上了。如果 sessionFactory 指向的 dataSource 可以根據客戶的 需求去連接客戶所需要的真正的數據源,即提供動態切換數據源的功能,那麼問題就解決了。那麼我們怎麼做呢?去修改那些我們要使用 的 dataSource 源碼嗎?這顯然不是一個好的方案,我們希望我們的修改與原dataSource 代碼是分離的。根據以上的分析,使 用 GoF 設計模式中的 Decorator 模式(裝飾者模式)應當是我們可以選擇的最佳方案。
什 么是「 Decorator 模式」?簡單點兒說就是當我們需要修改原有的功能,但我們又不願直接去修改原有的代碼時,設計一個 Decorator 套 在原有代碼外面。當我們使用 Decorator 的時候與原類完全一樣,當 Decorator 的某些功能卻已經修改為了我們需要修改的功 能。 Decorator 模式的結構如圖。
我 們本來需要修改圖中所有具體的 Component 類的一些功能,但卻並不是去直接修改它們的代碼,而是在它們的外面增加一 個 Decorator 。 Decorator 與具體的 Component 類都是繼承的 AbstractComponent ,因此它長得和具 體的 Component 類一樣,也就是說我們在使用 Decorator 的時候就如同在使用 ConcreteComponentA 或者 ConcreteComponentB 一樣,甚至那些使用 ConcreteComponentA 或者 ConcreteComponentB 的客 戶程序都不知道它們用的類已經改為了 Decorator ,但是 Decorator 已經對具體的 Component 類的部分方法進行了修改,執 行這些方法的結果已經不同了。
(二) 設計 MultiDataSource 類
現 在回到我們的問題,我們需要對 dataSource 的功能進行變更,但又不希望修改 dataSource 中的任何代碼。我這里指 的 dataSource 是所有實現 javax.sql.DataSource 介面的類,我們常用的包括 apache 提供的 org.apache.commons.dbcp.BasicDataSource 、 spring 提供的 org.springframework.jndi.JndiObjectFactoryBean 等,這些類我們不可能修改它們本身,更不可能對它們一 個個地修改以實現動態分配數據源的功能,同時,我們又希望使用 dataSource 的 sessionFactory 根本就感覺不到這樣的變 化。 Decorator 模式就正是解決這個問題的設計模式。
首先寫一個 Decorator 類,我取名叫 MultiDataSource,通過它來動態切換數據源 。同時在配置文件中將sessionFactory的dataSource屬性由原來的某個具體的dataSource改為MultiDataSource。如圖:
對 比原Decorator 模式, AbstractComponent 是一個抽象類,但在這里我們可以將這個抽象類用介面來代替,即 DataSource 介面,而 ConcreteComponent 就是那些 DataSource 的實現類, 如 BasicDataSource 、JndiObjectFactoryBean 等。 MultiDataSource 封裝了具體的 dataSource,並實現了數據源動態切換:
java 代碼
public class MultiDataSource implements DataSource {
private DataSource dataSource = null ;
public MultiDataSource(DataSource dataSource){
this .dataSource = dataSource;
}
public Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
//其它DataSource介面應當實現的方法
public DataSource getDataSource(){
return this .dataSource;
}
}
public void setDataSource(DataSource dataSource) {
this .dataSource = dataSource;
}
}
客 戶在發出請求的時候,將dataSourceName放到request中,然後把request中的數據源名通過調用 newMultiDataSource(dataSource) 時可以告訴 MultiDataSource 客戶需要的數據源,就可以實現動態切換數 據源了。但細心的朋友會發現這在單例的情況下就是問題的,因為 MultiDataSource 在系統中只有一個對象,它的實例變 量 dataSource 也只有一個,就如同一個靜態變數一般。正因為如此, 單例模式讓許多設計模式都不得不需要更改,這將在我的《「單例」更改了我 們的設計模式》中詳細討論。那麼,我們在單例模式下如何設計呢?
(三) 單例模式下的 MultiDataSource
在 單例模式下,由於我們在每次調用 MultiDataSource 的方法的時候, dataSource 都可能是不同的,所以我們不能 將 dataSource 放在實例變數 dataSource 中,最簡單的方式就是在方法 getDataSource() 中增加參數,告 訴 MultiDataSource 我到底調用的是哪個 dataSource :
java 代碼
public DataSource getDataSource(String dataSourceName){
log.debug( "dataSourceName:" +dataSourceName);
try {
if (dataSourceName== null ||dataSourceName.equals( "" )){
return this .dataSource;
}
return (DataSource) this .applicationContext.getBean(dataSourceName);
} catch (NoSuchBeanDefinitionException ex){
throw new DaoException( "There is not the dataSource
}
}
值得一提的是,我需要的數據源已經都在spring 的配置文件中注冊, dataSourceName 就是其對應的 id 。
xml 代碼
< bean id = "dataSource1"
class = "org.apache.commons.dbcp.BasicDataSource" >
< property name = "driverClassName" >
< value > oracle.jdbc.driver.OracleDriver value >
property >
......
bean >
< bean id = "dataSource2"
class = "org.apache.commons.dbcp.BasicDataSource" >
< property name = "driverClassName" >
< value > oracle.jdbc.driver.OracleDriver value >
property >
......
bean >
為了得到spring 的 ApplicationContext , MultiDataSource 類必須實現介面org.springframework.context.ApplicationContextAware ,並且實現方法:
java 代碼
private ApplicationContext applicationContext = null ;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this .applicationContext = applicationContext;
}
如此這樣,我就可以通過this . applicationContext .getBean(dataSourceName) 得到 dataSource 了。
(四) 通過線程傳遞 dataSourceName
查 看以上設計, MultiDataSource 依然無法運行,因為用戶在發出請求時,他需要連接什麼資料庫,其數據源名是放在 request 中的, 要將 request 中的數據源名傳給 MultiDataSource ,需要經過 BUS 和 DAO ,也就是說為了把數據源名傳 給 MultiDataSource , BUS 和 DAO 的所有方法都要增加 dataSourceName 的參數,這是我們不願看到的。寫一個 類,通過線程的方式跳過 BUS 和 DAO 直接傳遞給 MultiDataSource 是一個不錯的設計:
java 代碼
public class SpObserver {
private static ThreadLocal local = new ThreadLocal();
public static void putSp(String sp) {
local.set(sp);
}
public static String getSp() {
return (String)local.get();
}
}
做一個filter ,每次客戶發出請求的時候就調用 SpObserver.petSp ( dataSourceName ) ,將 request 中的dataSourceName 傳遞給 SpObserver 對象。 最後修改 MultiDataSource 的方法 getDataSource() :
java 代碼
public DataSource getDataSource(){
String sp = SpObserver.getSp();
return getDataSource(sp);
}
完整的MultiDataSource 代碼在附件中。
(五) 動態添加數據源
通 過以上方案,我們解決了動態分配數據源的問題,但你可能提出疑問:方案中的數據源都是配置在 spring 的 ApplicationContext 中,如果我在程序運行過程中動態添加數據源怎麼辦?這確實是一個問題,而且在我們的項目中也確實遇 到。 spring 的 ApplicationContext 是在項目啟動的時候載入的。載入以後,我們如何動態地載入新的 bean 到 ApplicationContext 中呢?我想到如果用 spring 自己的方法解決這個問題就好了。所幸的是,在查看 spring 的源代碼後,我找到了這樣的代碼,編寫了 DynamicLoadBean 類,只要 調用loadBean() 方法,就可以將某個或某 幾個配置文件中的 bean 載入到 ApplicationContext 中(見附件)。不通過配置文件直接載入對象,在spring 的源碼中也 有,感興趣的朋友可以自己研究。
(六) 在 spring 中配置
在完成了所有這些設計以後,我最後再嘮叨一句。我們應當在 spring 中做如下配置:
xml 代碼
< bean id = "dynamicLoadBean" class = "com.htxx.service..DynamicLoadBean" > bean >
< bean id = "dataSource" class = "com.htxx.service..MultiDataSource" >
< property name = "dataSource" >
< ref bean = "dataSource1" />
property >
bean >
< bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
< property name = "dataSource" >
< ref bean = "dataSource" />
property >
......
bean >
其中dataSource 屬性實際上更准確地說應當是 defaultDataSource ,即 spring 啟動時以及在客戶沒有指定數據源時應當指定的默認數據源。
該方案的優勢
以上方案與其它方案相比,它有哪些優勢呢?
首 先,這個方案完全是在 spring 的框架下解決的,數據源依然配置在 spring 的配置文件中, sessionFactory依然去配置它 的 dataSource 屬性,它甚至都不知道 dataSource 的改變。唯一不同的是在真正的 dataSource 與 sessionFactory 之間增加了一個 MultiDataSource 。
其 次,實現簡單,易於維護。這個方案雖然我說了這么多東西,其實都是分析,真正需要我們寫的代碼就只有 MultiDataSource 、 SpObserver 兩個類。 MultiDataSource 類真正要寫的只 有 getDataSource() 和getDataSource(sp) 兩個方法,而 SpObserver 類更簡單了。實現越簡單,出錯的可能 就越小,維護性就越高。
最 後,這個方案可以使單數據源與多數據源兼容。這個方案完全不影響 BUS 和 DAO 的編寫。如果我們的項目在開始之初是單數據源的情況下開發,隨著項 目的進行,需要變更為多數據源,則只需要修改 spring 配置,並少量修改 MVC 層以便在請求中寫入需要的數據源名,變更就完成了。如果我們的項 目希望改回單數據源,則只需要簡單修改配置文件。這樣,為我們的項目將增加更多的彈性。
特 別說明:實例中的DynamicLoadBean在web環境下運行會出錯,需要將類中AbstractApplicationContext改為 org.springframework.context.。
H. JAVA WEB一定要配置數據源嗎
不一定,你也可以直接從資料庫讀取數據,但是配置了一個數據源了,你就不用重復進行打開關閉資料庫的操作,這都是很浪費時間的操作
I. javaweb多數據源問題求解
很久沒用了,ssh的本機線程棧 creteria能localthreadd 里取的。大概就是這樣,要在xml裡面打開一個東西 把它變成全局的,記不清了,你試試吧
J. JavaWeb項目怎麼實現分站,或者說一個項目多個數據源求思路!
我會告訴你, 其實 a..com 和 b..com是兩個項目么 ?
本來就是把一個項目拆成多個子項目, 每個項目用自己的數據源