隨筆-86  評(píng)論-33  文章-0  trackbacks-0
          DataSource注入

          對(duì)于不同的數(shù)據(jù)庫(kù)存取需求,我們使用JDBC來(lái)解決這個(gè)問(wèn)題,對(duì)于不同的數(shù)據(jù)連接來(lái)源需求,Spring則提供了DataSource注入,更換數(shù)據(jù)來(lái)源只要在Bean定義文件中修改配置,而不用修改任何一行程序。

          因應(yīng)不同的系統(tǒng),應(yīng)用程序可能使用不同的數(shù)據(jù)來(lái)源,但如純綷的使用 JDBC、透過(guò)連接池、或是透過(guò)JNDI等等,數(shù)據(jù)來(lái)源的更動(dòng)是底層的行為,不應(yīng)影響到上層的業(yè)務(wù)邏輯,為此,您可以在需要取得連接來(lái)源的Bean上保留一個(gè)數(shù)據(jù)來(lái)源注入的接口,讓依賴(lài)的數(shù)據(jù)來(lái)源由該接口注入。例如我們來(lái)寫(xiě)一個(gè)簡(jiǎn)單的Bean:

          DataBean.java

          package  onlyfun.caterpillar; 
                                                                                       
          import  javax.sql.DataSource; 

          import  java.sql.Connection; 

          public   class  DataBean { 

              
          private  DataSource dataSource; 
                                                                                          
              
          public   void  setDataSource(DataSource dataSource) { 

                  
          this .dataSource  =  dataSource; 

              } 
                                                                                       
              
          public   void  testDataSource() { 

                  
          try  { 

                      Connection connection 
          =  dataSource.getConnection(); 

                      
          if (connection  !=   null

                          System.out.println(
          " test ok! " ); 

                  } 

                  
          catch  (Exception e) { 

                      e.printStackTrace(); 

                  } 

              } 

          }

          這是一個(gè)簡(jiǎn)單的測(cè)試Spring DataSource注入的程序,我們透過(guò)javax.sql.DataSource接口來(lái)注入數(shù)據(jù)來(lái)源,Spring提供了 org.springframework.jdbc.datasource.DriverManagerDataSource來(lái)取得 DataSource,它實(shí)作了javax.sql.DataSource,您將之當(dāng)作一個(gè)Bean,之后再注入DataBean中即可,Bean定義檔可以這么撰寫(xiě):

          <? xml version = " 1.0 "  encoding = " UTF-8 " ?>  

          <! DOCTYPE beans PUBLIC  " -//SPRING/DTD BEAN/EN "   " http://www.springframework.org/dtd/spring-beans.dtd " >  

          < beans >  

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

                  
          < property name = " driverClassName " >  

                      
          < value > com.mysql.jdbc.Driver </ value >  

                  
          </ property >  

                  
          < property name = " url " >  

                      
          < value > jdbc:mysql: // localhost:3306/TestDB</value> 

                  
          </ property >  

                  
          < property name = " username " >  

                      
          < value > caterpillar </ value >  

                  
          </ property >  

                  
          < property name = " password " >  

                      
          < value > 123456 </ value >  

                  
          </ property >  

              
          </ bean >  

                                                                                          

              
          < bean id = " dataBean "   class = " onlyfun.caterpillar.DataBean " >  

                  
          < property name = " dataSource " >  

                      
          < ref bean = " dataSource " />  

                  
          </ property >  

              
          </ bean >  

          </ beans >

          如果您之前只使用spring-core.jar這個(gè)類(lèi)別庫(kù),您還必須加入 spring-dao.jar, org.springframework.jdbc.datasource.DriverManagerDataSource是包括在這個(gè)類(lèi)別庫(kù)中,如果您使用的是spring.jar,當(dāng)中已經(jīng)包括了,無(wú)需加入任何的jar,當(dāng)然,為了使用JDBC,您必須要有JDBC驅(qū)動(dòng)程序的jar檔。

          可以用下面這段程序簡(jiǎn)單的測(cè)試一下:

          BeanDefinitionRegistry reg = new DefaultListableBeanFactory();

          XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(reg);

                                                                                          

          reader.loadBeanDefinitions(new ClassPathResource("bean.xml"));;

                                                                                         

          BeanFactory bf = (BeanFactory) reg;

          DataBean dataBean = (DataBean) bf.getBean("dataBean");

          dataBean.testDataSource();


          DriverManagerDataSource并沒(méi)有提供連接池的功能,只能作作簡(jiǎn)單的單機(jī)連接測(cè)試,現(xiàn)在假設(shè)連接測(cè)試沒(méi)有問(wèn)題了,您想要換上DBCP以獲得連接池的功能,則原程序不用更動(dòng),只要改改Bean定義檔就可以了:

          <? xml version = " 1.0 "  encoding = " UTF-8 " ?>  

          <! DOCTYPE beans PUBLIC  " -//SPRING/DTD BEAN/EN "   " http://www.springframework.org/dtd/spring-beans.dtd " >  

          < beans >  

              
          < bean id = " dataSource "   class = " org.apache.commons.dbcp.BasicDataSource "  destroy - method = " close " >  

                  
          < property name = " driverClassName " >  

                      
          < value > com.mysql.jdbc.Driver </ value >  

                  
          </ property >  

                  
          < property name = " url " >  

                      
          < value > jdbc:mysql: // localhost:3306/TestDB</value> 

                  
          </ property >  

                  
          < property name = " username " >  

                      
          < value > caterpillar </ value >  

                  
          </ property >  

                  
          < property name = " password " >  

                      
          < value > 123456 </ value >  

                  
          </ property >  

              
          </ bean >  

              
          < bean id = " dataBean "   class = " onlyfun.caterpillar.DataBean " >  

                  
          < property name = " dataSource " >  

                      
          < ref bean = " dataSource " />  

                  
          </ property >  

              
          </ bean >  

          </ beans >


          現(xiàn)在我們使用的是org.apache.commons.dbcp.BasicDataSource作為注入的 DataSource源,為了使用DBCP的功能,您必須要將commons-dbcp.jar加入CLASSPATH中,另外您還需要commons- pool.jar與commons-collections.jar,這些都可以在Spring的相依版本中的lib目錄下找到。

          注意到我們?cè)赿ataSource Bean上宣告了destroy-method,如此可以確保BeanFactory在關(guān)閉時(shí)也一并關(guān)閉BasicDataSource。

          如果您要直接使用JDBC來(lái)進(jìn)行數(shù)據(jù)存儲(chǔ),使用org.springframework.jdbc.datasource.DataSourceUtils來(lái)取得Connection會(huì)是更好的方式:

          Connection conn = DataSourceUtils.getConnection(dataSource);


          這樣作的好處是,所有的SQLException都被Spring的DataAccessException子類(lèi)CannotGetJdbcConnectionException包裝起來(lái)。您可以獲得更多的信息,并保證存儲(chǔ)層的可移值性。


          關(guān)閉Connection時(shí),可以用下面的方式:

          DataSourceUtils.closeConnectionIfNecessry(connection, dataSource);


          如果您的Servlet容器提供了JNDI資料源,您也可以簡(jiǎn)單的換上這個(gè)數(shù)據(jù)源:

          <? xml version = " 1.0 "  encoding = " UTF-8 " ?>  

          <! DOCTYPE beans PUBLIC  " -//SPRING/DTD BEAN/EN "   " http://www.springframework.org/dtd/spring-beans.dtd " >  

          < beans >  

              
          < bean id = " dataSource "   class = " org.springframework.indi.JndiObjectFactoryBean " >  

                  
          < property name = " jndiName " >  

                      
          < value > jdbc / TestDB </ value >  

                  
          </ property >  

              
          </ bean >  

              
          < bean id = " dataBean "   class = " onlyfun.caterpillar.DataBean " >  

                  
          < property name = " dataSource " >  

                      
          < ref bean = " dataSource " />  

                  
          </ property >  

              
          </ bean >  

          </ beans >


          為了使用org.springframework.indi.JndiObjectFactoryBean,您必須加入 spring-context.jar這個(gè)類(lèi)別庫(kù),jndiName實(shí)際上要根據(jù)您所設(shè)定的JNDI查詢(xún)名稱(chēng)

          posted on 2006-11-07 09:03 Derek.Guo 閱讀(5725) 評(píng)論(3)  編輯  收藏 所屬分類(lèi): Java

          評(píng)論:
          # re: Spring DataSource注入 2007-10-23 15:14 | leefu
          你好,我想問(wèn)下,用JNDI的 DataSource,然后在java應(yīng)用中用到DataBean,在DataBean中加上一個(gè)ExecuteQuery()方法,在頻繁的調(diào)用這個(gè)ExecuteQuery()方法的時(shí)候會(huì)出現(xiàn)連接池用完 ORA-04031: 無(wú)法分配 2816 字節(jié)的共享內(nèi)存,想問(wèn)一下,用JNDI的 DataSource的時(shí)候該怎么解決這個(gè)連接池的問(wèn)題,謝謝  回復(fù)  更多評(píng)論
            
          # re: Spring DataSource注入[未登錄](méi) 2007-11-05 22:00 | Derek
          @leefu
          你好!
          不管使用什么樣的數(shù)據(jù)源datasource;都需要處理關(guān)閉數(shù)據(jù)庫(kù)連接的問(wèn)題!!連接池與非連接池不同的是在于,連接是被正真關(guān)閉還是被返回池中!!
          通過(guò)JNDI的Datasource去獲取的連接,同樣需要你去CLOSE;否則池中的連接同樣會(huì)被用完的;
          那么關(guān)閉連接要么你純手工完成,要么使用SPRING的TEMPLATE,讓它幫你完成!  回復(fù)  更多評(píng)論
            
          # re: Spring DataSource注入[未登錄](méi) 2008-11-28 15:51 | 啊啊
          不錯(cuò),不像其他文章搞的很亂  回復(fù)  更多評(píng)論
            
          MSN:envoydada@hotmail.com QQ:34935442
          主站蜘蛛池模板: 法库县| 临湘市| 恩平市| 宜兰县| 云和县| 吉木乃县| 西乡县| 资源县| 延吉市| 平乐县| 琼结县| 星子县| 咸宁市| 衢州市| 郑州市| 镇雄县| 平乡县| 新巴尔虎左旗| 高安市| 武定县| 康马县| 平乐县| 栾川县| 武冈市| 高唐县| 泰宁县| 怀柔区| 兴仁县| 宝应县| 新竹市| 芦山县| 敦化市| 尉犁县| 金堂县| 呼玛县| 大新县| 班玛县| 农安县| 新余市| 资中县| 芒康县|