spring(16)------spring的数据源配置
在spring中,通過XML的形式實(shí)現(xiàn)數(shù)據(jù)源的注入有三種形式。
一。使用spring自帶的DriverManagerDataSource
使用DriverManagerDataSource配置數(shù)據(jù)源與直接使用jdbc在效率上沒有多大的差別,使用DriverManagerDataSource配置數(shù)據(jù)源
的代碼實(shí)比例如以下,這里重點(diǎn)研究spring的數(shù)據(jù)源配置。就採用spring編程式事務(wù)處理來來研究數(shù)據(jù)源的配置。
所須要的jar包和spring編程式配置:http://blog.csdn.net/yhl_jxy/article/details/51167351
(1)HelloDAO類:
package com.lanhuigu.spring.dao;import javax.sql.DataSource;import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate;public class HelloDAO {private DataSource dataSource;private PlatformTransactionManager transactionManager;//通過set方式注入public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}public void setTransactionManager(PlatformTransactionManager transactionManager) {this.transactionManager = transactionManager;}//=============編程式事務(wù)處理的3種編寫形式====================//第一種編寫public int create(String msg) {System.out.println(msg+"開始!"); //使用TransactionTemplate進(jìn)行事務(wù)處理編程 TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); //調(diào)用TransactionTemplate的execute方法 Object result = transactionTemplate.execute( new TransactionCallback() { //覆蓋TransactionCallback的doInTransaction()方法 @Override public Object doInTransaction(TransactionStatus status) { // TODO Auto-generated method stub //在該方法內(nèi)對(duì)數(shù)據(jù)庫進(jìn)行添加操作 System.out.println("加入對(duì)象進(jìn)行"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); //第一次運(yùn)行不打開,第二次運(yùn)行打開 //jdbcTemplate.update("insert into t_user_main values(2,'test',24)"); jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); System.out.println("加入對(duì)象結(jié)束"); return null; } } ); return 0; } //另外一種編寫 /*public int create(String msg) { System.out.println(msg+"開始!"); DefaultTransactionDefinition dtd = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(dtd); try { //使用JdbcTemplate與數(shù)據(jù)庫進(jìn)行交互 System.out.println("加入對(duì)象進(jìn)行"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); } catch (DataAccessException ex) { // TODO: handle exception transactionManager.rollback(status); throw ex; } finally { transactionManager.commit(status); } return 0; }*/ //第三種編寫 /*public int create(String msg) { System.out.println(msg+"開始。"); TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { // TODO Auto-generated method stub JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); } }); return 0; }*/ /*//============聲明式事務(wù)編程============ public int create(String msg) { System.out.println(msg+"開始"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); //新增數(shù)據(jù) jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); System.out.println(msg+"結(jié)束"); return 0; }*/ }
(2)使用spring自帶的DataSourceTransactionManager配置數(shù)據(jù)源: <?xml version="1.0" encoding="UTF-8"?><!--- Application context definition for JPetStore's business layer.- Contains bean references to the transaction manager and to the DAOs in- dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").--> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><!-- spring編程式事務(wù)配置 --><!-- 1.配置數(shù)據(jù)源(dataSource) --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!-- oracle數(shù)據(jù)庫驅(qū)動(dòng) --><property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property><!-- 數(shù)據(jù)庫連接 --><property name="url"><value>jdbc:oracle:thin:@localhost:1521/XE</value></property><!-- 數(shù)據(jù)庫用戶名 --><property name="username"><value>system</value></property><!-- 數(shù)據(jù)庫密碼 --><property name="password"><value>123456</value></property></bean><!-- 2.設(shè)定transactionManager --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 這里配置的dataSource是DataSourceTransactionManager類中的屬性,在類中有著屬性的定義:private DataSource dataSource; 跟以下配置的HelloDAO中的dataSource不是用在一個(gè)地方。是一個(gè)東西用在兩個(gè)地方--><property name="dataSource"><ref bean="dataSource"/></property></bean><!-- 3.配置事務(wù)管理目標(biāo)類 --><bean id="helloDAO" class="com.lanhuigu.spring.dao.HelloDAO"><!-- dataSource屬性 --><property name="dataSource"><ref bean="dataSource"/></property><!-- transactionManager屬性 --><property name="transactionManager"><ref bean="transactionManager"/></property> </bean></beans> (3)測(cè)試程序: package com.lanhuigu.spring.test;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.lanhuigu.spring.dao.HelloDAO; import com.lanhuigu.spring.impl.IUser;public class TestJDBCTemplate {@Testpublic void testJDBCTemplate(){//1.創(chuàng)建spring容器ApplicationContext actx =new ClassPathXmlApplicationContext("/applicationContext.xml");//2.編程式測(cè)試HelloDAO helloDAO = (HelloDAO) actx.getBean("helloDAO");helloDAO.create("加入對(duì)象");} } (4)總結(jié):之所以說使用這樣的方式跟jdbc直接操作數(shù)據(jù)庫效率上沒有多大差別,是由于DriverManagerDataSource建立連接是僅僅要有連接就新建一個(gè)connection,
根本沒有連接池的作用,這樣做的話,數(shù)據(jù)庫一直開連接,數(shù)據(jù)庫崩掉是早晚的事。
二。使用DBCP配置連接池
須要添加jar包例如以下:
在目錄spring-framework-2.5.6\lib\jakarta-commons下的commons-collections.jar,commons-dbcp.jar,commons-pool.jar。
改動(dòng)上面使用上面DriverManagerDataSource配置數(shù)據(jù)源的配置文件,改動(dòng)為DBCP配置數(shù)據(jù)源的方式,改動(dòng)后的xml例如以下。其它不變:
<?xml version="1.0" encoding="UTF-8"?><!--- Application context definition for JPetStore's business layer.- Contains bean references to the transaction manager and to the DAOs in- dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").--> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><!-- spring編程式事務(wù)配置 --><!-- 1.配置數(shù)據(jù)源(dataSource) --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><!-- oracle數(shù)據(jù)庫驅(qū)動(dòng) --><property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property><!-- 數(shù)據(jù)庫連接 --><property name="url"><value>jdbc:oracle:thin:@localhost:1521/XE</value></property><!-- 數(shù)據(jù)庫用戶名 --><property name="username"><value>system</value></property><!-- 數(shù)據(jù)庫密碼 --><property name="password"><value>123456</value></property><!-- 最大連接數(shù)據(jù)庫連接數(shù),設(shè)置為0時(shí)。表示沒有限制 --><property name="maxActive"><value>255</value></property><!-- 最大等待連接中的數(shù)量,設(shè)置為0時(shí),表示沒有限制 --><property name="maxIdle"><value>2</value></property><!-- 最大等待秒數(shù),單位為毫秒。 超過時(shí)間會(huì)報(bào)出錯(cuò)誤信息 --><property name="maxWait"><value>50000</value></property></bean><!-- 2.設(shè)定transactionManager --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 這里配置的dataSource是DataSourceTransactionManager類中的屬性。在類中有著屬性的定義:private DataSource dataSource; 跟以下配置的HelloDAO中的dataSource不是用在一個(gè)地方。是一個(gè)東西用在兩個(gè)地方--><property name="dataSource"><ref bean="dataSource"/></property></bean><!-- 3.配置事務(wù)管理目標(biāo)類 --><bean id="helloDAO" class="com.lanhuigu.spring.dao.HelloDAO"><!-- dataSource屬性 --><property name="dataSource"><ref bean="dataSource"/></property><!-- transactionManager屬性 --><property name="transactionManager"><ref bean="transactionManager"/></property> </bean></beans> 注意:當(dāng)你執(zhí)行程序時(shí),報(bào)錯(cuò)的話,是HelloDAO中
jdbcTemplate.update("insert into t_user_main values(1,'test',24)");插入數(shù)據(jù)id反復(fù)導(dǎo)致的,
換個(gè)id或刪掉數(shù)據(jù)庫表的數(shù)據(jù)。然后再執(zhí)行。
關(guān)于DBCP的總結(jié):
1. 首先得了解配置文件里的屬性:
BasicDataSource提供close()方法關(guān)閉數(shù)據(jù)源。一定記得設(shè)置destroy-method=”close”。以便spring容器關(guān)閉時(shí)。
數(shù)據(jù)源可以得到正常的關(guān)閉。還有非常多經(jīng)常使用的property屬性例如以下:
defaultAutoCommit:設(shè)置從數(shù)據(jù)源中返回的連接是否採用自己主動(dòng)提交的機(jī)制,默覺得true;
defaultReadOnly:設(shè)置數(shù)據(jù)源是否僅能運(yùn)行僅僅讀操作,默覺得false;
maxActive:最大連接數(shù)據(jù)庫連接數(shù),設(shè)置為0時(shí),表示沒有限制;
mmaxIdle:最大等待連接中的數(shù)量,設(shè)置為0時(shí),表示沒有限制;
maxWait:最大等待秒數(shù)。單位為毫秒。超時(shí)報(bào)錯(cuò);
validationQuery:用于驗(yàn)證連接是否成功的查詢SQL語句。SQL語句必須至少要返回一行數(shù)據(jù);
removeAbandoned:是否自我中斷,默認(rèn)是false;
removeAbandonedTimout:幾秒后數(shù)據(jù)庫連接會(huì)自己主動(dòng)斷開,在removeAbandoned為true,提供該值;
logAbandoned:是否記錄中斷事件,默覺得false;
2.使用連接池
使用這樣的方式的優(yōu)點(diǎn)在于數(shù)據(jù)庫連接時(shí)建立了連接池。連接池的優(yōu)點(diǎn)就是當(dāng)你建立連接時(shí)。從連接池中找。找到就使用已有連接,
找不到新建連接,類推到最大連接數(shù)時(shí),假設(shè)沒有空暇可用連接,就等待。用完就釋放到連接池。做到資源使用最大化。不會(huì)
無限制的建立連接。把數(shù)據(jù)庫搞崩了。
三,使用C3P0連接數(shù)據(jù)源
須要增加c3p0的jar包,這里使用c3p0-0.9.1.2.jar,改動(dòng)spring數(shù)據(jù)源配置文件。
<?xml version="1.0" encoding="UTF-8"?
> <!-- - Application context definition for JPetStore's business layer. - Contains bean references to the transaction manager and to the DAOs in - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation"). --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- spring編程式事務(wù)配置 --> <!-- 1.配置數(shù)據(jù)源(dataSource) --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!-- oracle數(shù)據(jù)庫驅(qū)動(dòng) --> <property name="driverClass"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <!-- 數(shù)據(jù)庫連接 --> <property name="jdbcUrl"> <value>jdbc:oracle:thin:@localhost:1521/XE</value> </property> <!-- 數(shù)據(jù)庫username --> <property name="user"> <value>system</value> </property> <!-- 數(shù)據(jù)庫密碼 --> <property name="password"> <value>123456</value> </property> </bean> <!-- 2.設(shè)定transactionManager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 這里配置的dataSource是DataSourceTransactionManager類中的屬性, 在類中有著屬性的定義:private DataSource dataSource; 跟以下配置的HelloDAO中的dataSource不是用在一個(gè)地方,是一個(gè)東西用在兩個(gè)地方--> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean> <!-- 3.配置事務(wù)管理目標(biāo)類 --> <bean id="helloDAO" class="com.lanhuigu.spring.dao.HelloDAO"> <!-- dataSource屬性 --> <property name="dataSource"> <ref bean="dataSource"/> </property> <!-- transactionManager屬性 --> <property name="transactionManager"> <ref bean="transactionManager"/> </property> </bean> </beans>
使用總結(jié): ComboPooledDataSource和BasicDataSource一樣都提供一個(gè)當(dāng)spring容器關(guān)閉時(shí)用于數(shù)據(jù)源正確關(guān)閉的close()方法。
C3P0擁有比DBCP更豐富的配置屬性,通過這些屬性,能夠?qū)?shù)據(jù)源進(jìn)行各種有效的控制:?
acquireIncrement:當(dāng)連接池中的連接用完時(shí),C3P0一次性創(chuàng)建新連接的數(shù)目;?
acquireRetryAttempts:定義在從數(shù)據(jù)庫獲取新連接失敗后反復(fù)嘗試獲取的次數(shù)。默覺得30;
acquireRetryDelay:兩次連接中間隔時(shí)間,單位毫秒,默覺得1000;?
autoCommitOnClose:連接關(guān)閉時(shí)默認(rèn)將全部未提交的操作回滾。默覺得false;?
automaticTestTable: C3P0將建一張名為Test的空表,并使用其自帶的查詢語句進(jìn)行測(cè)試。
假設(shè)定義了這個(gè)參數(shù),那么屬性preferredTestQuery將被忽略。
你不能在這張Test表上進(jìn)行不論什么操作,它將中為C3P0測(cè)試所用,默覺得null;?
?breakAfterAcquireFailure:獲取連接失敗將會(huì)引起全部等待獲取連接的線程拋出異常。
可是數(shù)據(jù)源仍有效保留。
并在下次調(diào)?? 用getConnection()的時(shí)候繼續(xù)嘗試獲取連接。
假設(shè)設(shè)為true,那么在嘗試獲取連接失敗后該數(shù)據(jù)源將申明已斷開并永久關(guān)閉。默覺得 false;?
checkoutTimeout:當(dāng)連接池用完時(shí)client調(diào)用getConnection()后等待獲取新連接的時(shí)間,超時(shí)后將拋出SQLException,
如設(shè)為0則無限期等待。單位毫秒,默覺得0;?
connectionTesterClassName: 通過實(shí)現(xiàn)ConnectionTester或QueryConnectionTester的類來測(cè)試連接,類名需設(shè)置為全限定名。
默覺得 com.mchange.v2.C3P0.impl.DefaultConnectionTester;?
idleConnectionTestPeriod:隔多少秒檢查全部連接池中的空暇連接,默覺得0表示不檢查;?
initialPoolSize:初始化時(shí)創(chuàng)建的連接數(shù),應(yīng)在minPoolSize與maxPoolSize之間取值。
默覺得3;?
maxIdleTime:最大空暇時(shí)間,超過空暇時(shí)間的連接將被丟棄。
為0或負(fù)數(shù)則永不丟棄。默覺得0。?
maxPoolSize:連接池中保留的最大連接數(shù)。
默覺得15;?
maxStatements:JDBC的標(biāo)準(zhǔn)參數(shù)。用以控制數(shù)據(jù)源內(nèi)載入的PreparedStatement數(shù)量。
但因?yàn)轭A(yù)緩存的Statement屬 于單個(gè)Connection而不是整個(gè)連接池。
所以設(shè)置這個(gè)參數(shù)須要考慮到多方面的因素。
假設(shè)maxStatements與 maxStatementsPerConnection均為0,則緩存被關(guān)閉。默覺得0;?
maxStatementsPerConnection:連接池內(nèi)單個(gè)連接所擁有的最大緩存Statement數(shù)。
默覺得0;?
numHelperThreads:C3P0是異步操作的。緩慢的JDBC操作通過幫助進(jìn)程完畢。擴(kuò)展這些操作能夠有效的提升性能,
通過多線程實(shí)現(xiàn)多個(gè)操作同一時(shí)候被運(yùn)行。
默覺得3。?
preferredTestQuery:定義全部連接測(cè)試都運(yùn)行的測(cè)試語句。
在使用連接測(cè)試的情況下這個(gè)參數(shù)能顯著提高測(cè)試速度。
測(cè)試的表必須在初始數(shù)據(jù)源的時(shí)候就存在。默覺得null。?propertyCycle: 用戶改動(dòng)系統(tǒng)配置參數(shù)運(yùn)行前最多等待的秒數(shù)。默覺得300。?
testConnectionOnCheckout:因性能消耗大請(qǐng)僅僅在須要的時(shí)候使用它。假設(shè)設(shè)為true那么在每一個(gè)connection提交的時(shí)候都 將校驗(yàn)其有效性。建議使用idleConnectionTestPeriod或automaticTestTable?
等方法來提升連接測(cè)試的性能。默覺得false;?
testConnectionOnCheckin:假設(shè)設(shè)為true那么在取得連接的同一時(shí)候?qū)⑿r?yàn)連接的有效性。
默覺得false。
這樣的方式須要在Tomcat中server.xml中配置數(shù)據(jù)源,也就是把上面的數(shù)據(jù)配置放在server.xml中,同一時(shí)候須要在spring配置文件里進(jìn)行jndi配置。很麻煩。
一般不用。
轉(zhuǎn)載于:https://www.cnblogs.com/mthoutai/p/7230772.html
總結(jié)
以上是生活随笔為你收集整理的spring(16)------spring的数据源配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 9 揭秘(14. HTTP/2
- 下一篇: 扩号匹配问题