何爲DataSource java
DataSource 接口是 JDBC 2.0 API 中的新增內容,它提供了鏈接到數據源的另外一種方法。
做爲 DriverManager
工具的替代項,DataSource
對象是獲取鏈接的首選方法。
實現 DataSource 接口的對象一般在基於JNDI API 的命名服務中註冊。mysql
無論經過何種持久化技術,都必須經過數據鏈接訪問數據庫,在傳統的應用中數據鏈接能夠經過DriverManager獲的,
在Spring中,數據鏈接通常是經過數據源得到的。在以往的應用中,數據源通常是 Web應用服務器提供的。
在Spring中,你不但能夠經過JNDI獲取應用服務器的數據源,也能夠直接在Spring容器中配置數據源,
此外,你還能夠 經過代碼的方式建立一個數據源,以便進行無依賴的單元測試。 web
DataSource API定義:
spring
package javax.sql; import java.sql.Connection; import java.sql.SQLException; import java.sql.Wrapper; public interface DataSource extends CommonDataSource,Wrapper { Connection getConnection() throws SQLException; Connection getConnection(String username, String password) throws SQLException; }
在Spring中配置Datasourcesql
一、JDBC數據庫
Spring自己也提供了一個簡單的數據源實現類DriverManagerDataSource ,
它位於org.springframework.jdbc.datasource包中。這個類實現了javax.sql.DataSource接口,
但它並無提供池化鏈接的機制,每次調用getConnection()獲取新鏈接時,只是簡單地建立一個新的鏈接。
所以,這個數據源類比較適合在單元測試 或簡單的獨立應用中使用,由於它不須要額外的依賴類。apache
<!-- 配置Spring DriverManagerDatasource數據源從中獲取connection,引入數據庫驅動 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:jdbc.properties</value> </property> </bean> <bean id="dataSource" destroy-method="close" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; public class DriverManagerDataSource extends AbstractDriverBasedDataSource { public DriverManagerDataSource() { } public DriverManagerDataSource(String url) { setUrl(url); } public DriverManagerDataSource(String url, String username, String password) { setUrl(url); setUsername(username); setPassword(password); } public DriverManagerDataSource(String url, Properties conProps) { setUrl(url); setConnectionProperties(conProps); } public DriverManagerDataSource(String driverClassName, String url, String username, String password) { setDriverClassName(driverClassName); setUrl(url); setUsername(username); setPassword(password); } public void setDriverClassName(String driverClassName) { Assert.hasText(driverClassName, "Property 'driverClassName' must not be empty"); String driverClassNameToUse = driverClassName.trim(); try { Class.forName(driverClassNameToUse, true, ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException ex) { IllegalStateException ise = new IllegalStateException("Could not load JDBC driver class [" + driverClassNameToUse + "]"); ise.initCause(ex); throw ise; } if (logger.isInfoEnabled()) { logger.info("Loaded JDBC driver: " + driverClassNameToUse); } } protected Connection getConnectionFromDriver(Properties props) throws SQLException { String url = getUrl(); if (logger.isDebugEnabled()) { logger.debug("Creating new JDBC DriverManager Connection to [" + url + "]"); } return getConnectionFromDriverManager(url, props); } protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException { return DriverManager.getConnection(url, props); } }
DriverManagerDataSource創建鏈接是隻要有鏈接就新建一個connection,根本沒有鏈接池的做用。 tomcat
Spring在第三方依賴包中包含了兩個數據源的實現類包,其一是Apache的DBCP,其二是 C3P0。
二、DBCP
DBCP類包位於 /lib/jakarta-commons/commons-dbcp.jar,DBCP是一個依賴 Jakarta commons-pool對象池機制的數據庫鏈接池,
因此在類路徑下還必須包括/lib/jakarta- commons/commons-pool.jar。服務器
<!-- 配置Spring dbcp Datasource數據源從中獲取connection,引入commons-dbcp、commons-pool包,數據庫驅動 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:jdbc.properties</value> </property> </bean> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
BasicDataSource.java
app
public class BasicDataSource implements DataSource { static { // Attempt to prevent deadlocks - see DBCP - 272 DriverManager.getDrivers(); } . . . }
C3P0是一個開放源代碼的JDBC數據源實現項目,C3P0類包位於Spring中lib/c3p0/c3p0-0.9.1.2.jar。
<!-- 配置Spring ComboPooledDataSource數據源從中獲取connection,引入c3p0-0.9.1.2.jar,數據庫驅動 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:jdbc.properties</value> </property> </bean> <bean id="dataSource" destroy-method="close" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClassName}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
經過查看ComboPooledDataSource的源碼咱們發現此處的屬性設置和上面不一樣,分別爲driverClass、jdbcUrl、user。
四、JNDI(Java Naming and Directory Interface)
若是應用配置在高性能的應用服務器(如WebLogic或Websphere等)上或Jboss、Tomcat等,咱們可能更但願使用應用服務器自己提供的數據源。
應用服務器的數據源使用JNDI使用,Spring爲此專門提供引用JNDI資源的org\springframework\jndi\JndiObjectFactoryBean類。
以tomcat6爲例:
一、在tomcat目錄下conf\context.xml中的<Context>標籤中加入
<Resource name="jndi" auth="Container" type="javax.sql.DataSource" password="mysql5" username="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/spring" maxActive="5" maxIdle="2" maxWait="3000" />
<resource-ref> <res-ref-name>jndi</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
<!-- 從Tomcat配置的JNDI服務獲取數據源--> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jndi"/> </bean>
xsi:schemaLocation="http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
<!-- Spring 2.0爲獲取J2EE資源提供了一個jee命名空間,經過jee命名空間,能夠有效地簡化J2EE資源的引用。 --> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jndi"/>