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