原文链接:http://zhuqiuhui.space/Blogs/2017/04/spring-tx-2.html
一、概览
实质上,JDBC连接数据库的方式一般可以分为两种,一种采用java.sql.DriverManager类(即JDBC驱动程序管理器),另一种采用JDBC中提供的实现DataSource接口的类(数据源)。更多人喜欢使用数据源的方式,相对于DriverManager的优点有:
- 首先,程序不需要像使用DriverManager一样对加载的数据库驱动程序信息进行硬编码,程序员可以选择先在JNDI中注册这个数据源对象,然后在程序中使用一个逻辑名称来引用它,JNDI会自动根据你给出的名称找到与这个名称绑定的DataSource对象,然后就可以使用这个 DataSource对象来建立和具体数据库的连接了。
- 其次,使用实现了DataSource接口的类所具有的第二个优势体现在连接池和分布式事务上。连接池通过对连接的复用而不是新建一个物理连接来显著地提高程序的效率,从而适用于任务繁忙、负担繁重的企业级分布式事务。
通俗一点:
- DataSource创建的connection既有基本实现,也有连接池实现(可以复用,DataSource帮我们实现了复用机制),而DriverManager创建的connection则不能复用(当然自己写连接池,自己来实现复用机制也是可以的),所以sun公司规定连接池技术需要实现DataSource接口。
- DataSource中封装了DriverManager的使用,使用DataSource的一个好处是可以在外边配置(如C3P0直接修改xml文件,不用自己写配置文件db.properties)。
- 配置DataSource,由容器来获取Connection并结合连接池的应用比直接使用DriverManager操作JDBC效率高一些。
二、连接方式
2.1 使用java.sql.DriverManager类(传统方式)
//1.驱动注册程序 --内部执行了RegisterDriver
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象
conn = DriverManager.getConnection(url, user, password);
//3.创建Statement
stmt = conn.createStatement();
//4.准备sql
String sql = "sql语句";
//5.发送sql语句,执行sql语句,得到返回结果
int count = stmt.executeUpdate(sql);
//6.输出
System.out.println("影响了"+count+"行!")
2.2 实现javax.sql.DataSource接口的类
作为DriverManager设施的替代项,DataSource对象是获取连接的首选方法,实现 DataSource接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API的命名服务中注册。
DataSource 接口由驱动程序供应商实现,共有三种类型的实现:
- 基本实现 - 生成标准 Connection 对象
- 连接池实现 - 生成自动参与连接池的 Connection 对象,此实现与中间层连接池管理器一起使用。
- 分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,并且几乎始终参与连接池,此实现与中间层事务管理器一起使用,并且几乎始终与连接池管理器一起使用。
注:(1)DataSource是一个接口,而具体的实现是由驱动提供厂商来确定的,也就是说,是否实现连接池技术,也由厂商确定的。
(2)通过 DataSource 对象访问的驱动程序不会向 DriverManager 注册。通过查找操作检索 DataSource 对象,然后使用该对象创建 Connection 对象。使用基本的实现,通过 DataSource 对象获取的连接与通过 DriverManager 设施获取的连接相同。
2.3 DBCP连接池(实现了javax.sql.DataSource接口)
DBCP(Database Connection Pool)是一个依赖Jakarta commons-pool对象池机制的数据库连接池,J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用 就可以使用这个连接。 相当于是优化了DataSource的一种工具。
核心类是:BasicDataSource,其实现了javax.sql.DataSource接口,还是看源码比较方便:
public class BasicDataSource implements DataSource {
static {
DriverManager.getDrivers();
}
//有兴趣可以研究源码,这里不再列出......
}
在Spring中配置方式:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatisTest" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
代码方式:
// DBCP连接池核心类
BasicDataSource dataSouce = new BasicDataSource();
// 连接池参数配置:初始化连接数、最大连接数 / 连接字符串、驱动、用户、密码
dataSouce.setUrl("jdbc:mysql://localhost:3306/mybatisTest");
dataSouce.setDriverClassName("com.mysql.jdbc.Driver");
dataSouce.setUsername("root");
dataSouce.setPassword("123456");
dataSouce.setInitialSize(3); // 初始化连接
dataSouce.setMaxActive(6); // 最大连接
// 获取连接
Connection con = dataSouce.getConnection();
con.prepareStatement("delete from admin where id=3").executeUpdate();
// 关闭
con.close();
2.4 使用C3P0连接池(Spring框架自带)
在Spring中的配置方式:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="checkoutTimeout" value="30000" />
<property name="maxPoolSize" value="15" />
<property name="idleConnectionTestPeriod" value="180" />
<property name="maxIdleTime" value="180" />
</bean>
代码方式:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置连接参数:url、驱动、用户密码、初始连接数、最大连接数
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc_demo");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setInitialPoolSize(3);
dataSource.setMaxPoolSize(6);
dataSource.setMaxIdleTime(1000);
Connection con = dataSource.getConnection();
// 执行更新
con.prepareStatement("delete from admin where id=7").executeUpdate();
// 关闭
con.close();
参考: java连接数据库的四种方式