文档章节

Spring DataSource

冰雷卡尔
 冰雷卡尔
发布于 2012/06/04 21:56
字数 1442
阅读 3082
收藏 6

何为DataSource

DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。
作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法
实现 DataSource 接口的对象通常在基于JNDI API 的命名服务中注册。

不管通过何种持久化技术,都必须通过数据连接访问数据库,在传统的应用中数据连接可以通过DriverManager获的,
在Spring中,数据连接一般是通过数据源获得的。在以往的应用中,数据源一般是 Web应用服务器提供的。
在Spring中,你不但可以通过JNDI获取应用服务器的数据源,也可以直接在Spring容器中配置数据源,
此外,你还可以 通过代码的方式创建一个数据源,以便进行无依赖的单元测试。

DataSource API定义:

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中配置Datasource

1、JDBC

Spring本身也提供了一个简单的数据源实现类DriverManagerDataSource ,
它位于org.springframework.jdbc.datasource包中。这个类实现了javax.sql.DataSource接口,
但它并没有提供池化连接的机制,每次调用getConnection()获取新连接时,只是简单地创建一个新的连接。
因此,这个数据源类比较适合在单元测试 或简单的独立应用中使用,因为它不需要额外的依赖类。

<!-- 配置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,根本没有连接池的作用。

Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0。

2、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

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;

3、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。

4、JNDI(Java Naming and Directory Interface)

如果应用配置在高性能的应用服务器(如WebLogic或Websphere等)上或Jboss、Tomcat等,我们可能更希望使用应用服务器本身提供的数据源。
应用服务器的数据源使用JNDI使用,Spring为此专门提供引用JNDI资源的org\springframework\jndi\JndiObjectFactoryBean类。

以tomcat6为例:
1、在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"
/>

2、修改项目的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>

3、在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"/>

© 著作权归作者所有

上一篇: 世界环境日
下一篇: Never Give UP
冰雷卡尔
粉丝 30
博文 116
码字总数 81854
作品 0
深圳
程序员
私信 提问
加载中

评论(1)

李血甜
李血甜
很不错,挺全面。希望多一些带回配置的讲解,总之,谢谢楼主!
spring boot jdbc Failed to determine a suitable driver class

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested ......

zero1814
02/13
115
0
怎样排查 Cannot determine embedded database driver class for database type NONE

调试排查 Cannot determine embedded database driver class for database type NONE 的错误 把工程导入IDE里,直接启动应用,抛出来的异常信息是: 其实这时有两个思路,直接google搜索Can...

小致dad
03/20
45
0
江湖救急:maven打包了dubbo服务的一个jar包,本机运行可以,虚拟机不行

我搭建dubbo服务,用maven打包了一个服务,本地运行没问题,但是放到虚拟机上,运行就出问题了 The last packet sent successfully to the server was 0 milliseconds ago. The driver has n...

君千殇520
2016/10/13
2.3K
4
Datasource V1.0 发布,分库分表-分布式

Datasource V1.0 发布,Datasource 是分布式数据源(Common-datasource) 继承spring 框架中的AbstractDatasource 的实现类.兼容spring 框架中的datasourceUtil 类, datasourceUtil 类的作用是...

liubingsmile
2015/03/23
3.6K
15
junit 测试错误: Failed to load ApplicationContext

java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegat......

Liem_
2016/08/11
2.8K
2

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
2.4K
15
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
41
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
40
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
61
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部