Spring DataSource

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


DriverManagerDataSource extends AbstractDriverBasedDataSource extends AbstractDataSource implements DataSource

DriverManagerDataSource.java

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

BasicDataSource提供了close()方法關閉數據源,因此必須設定destroy-method=」close」屬性,
以便Spring容器關閉時,數據源可以正常關閉。除以上必須的數據源屬性外,還有一些經常使用的屬性:
defaultAutoCommit:設置從數據源中返回的鏈接是否採用自動提交機制,默認值爲 true;
defaultReadOnly:設置數據源是否僅能執行只讀操做, 默認值爲 false;
maxActive:最大鏈接數據庫鏈接數,設置爲0時,表示沒有限制;
maxIdle:最大等待鏈接中的數量,設置爲0時,表示沒有限制;
maxWait:最大等待秒數,單位爲毫秒, 超過期間會報出錯誤信息;
validationQuery:用於驗證鏈接是否成功的查詢SQL語句,SQL語句必須至少要返回一行數據;
removeAbandoned:是否自我中斷,默認是 false ;
removeAbandonedTimeout:幾秒後數據鏈接會自動斷開,在removeAbandoned爲true,提供該值;
logAbandoned:是否記錄中斷事件, 默認爲 false;

三、C3P0

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

二、修改項目的web.xml文件加入
<resource-ref>
  	<res-ref-name>jndi</res-ref-name>
  	<res-type>javax.sql.DataSource</res-type>
  	<res-auth>Container</res-auth>
</resource-ref>

三、在spring配置文件中配置Datasource
<!-- 從Tomcat配置的JNDI服務獲取數據源-->
	<bean id="dataSource" 
		class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="java:comp/env/jndi"/>
	</bean>

咱們也能夠採用下面的方式,可是要加入如下命名空間
xmlns:jee="http://www.springframework.org/schema/jee"

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"/>
相關文章
相關標籤/搜索