Data Source与数据库连接池简介(JDBC简介)

目录
  • 起源
    • 为何放弃DriverManager
    • 连接池
    • 数据源
  • 实现
    • 核心架构
    • DataSource
    • API
    • 小结
  • 应用
    • 数据库连接池示例
  • 总结

DataSource是作为DriverManager的替代品而推出的,DataSource 对象是获取连接的首选方法。

起源

为何放弃DriverManager

DriverManager负责管理驱动程序,并且使用已注册的驱动程序进行连接。

//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//数据库连接所需参数
String user = "root";
String password = "123456";
String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";
//2、获取连接对象
Connection conn = DriverManager.getConnection(url, user, password);

使用DriverManager的一般形式如上面代码所示

直接使用DriverManager的这种形式,通常需要将驱动程序硬编码到项目中(JDBC4.0后可以自动注册驱动程序)

而且最重要的是DriverManager的getConnection方法获取的连接,是建立与数据库的连接,是建立与数据库的连接,是建立与数据库的连接。

但是建立与数据库的连接是一项较耗资源的工作,频繁的进行数据库连接建立操作会产生较大的系统开销。

随着企业级应用复杂度的提升以及对性能要求的提高,这一点是难以接受的。

连接池

既然每次使用时都重新建立与数据库之间的连接,会产生较大的系统开销

是否可以事先创建一些连接备用,当需要时,从这些连接中选择一个提供出去;当连接使用完毕后,并不是真正的关闭,而是将这些数据状态还原,然后继续等待下一个人使用?

比如滑雪场会租赁雪具滑雪服等,如果你不是资深玩家,你没有必要浪费钱买,即使你不差钱,每次去滑雪场都不能轻装上阵,每次都要携带很多装备,也是一件麻烦事。

这种没必要的花费或者麻烦其实都是一种开销。

连接池的核心与租用的理念有类似的点,重复使用可以提高连接的利用率,减少开销(当然连接池的使用并不需要你花费一笔租金)

连接的持有是消耗空间的,但是现在绝大多数场景下,磁盘空间并没有那么金贵,我们更关心的是性能,所以空间换取时间,连接池的逻辑被广泛应用。

数据源

DriverManager只是建立与数据库之间的连接,如何才能将连接池的概念应用其中?

一种很自然的方式就是提供一个薄层的封装,建立一个中间层,这个中间层将DriverManager生成的连接,组织到连接池中,然后从池中提供连接。

Data Source就是DriverManager的一种替代角色,对外呈现就类似于一个DriverManager,拥有对外提供连接的能力直接使用DriverManager,驱动程序与管理器是“服务者---管理者”的形式,借助于管理者才能提供服务。Data Source将驱动程序的概念淡化了,突出驱动程序能够提供的服务与能力,将驱动程序提供的服务与能力抽象为Data Source数据源这一角色。

DataSource中获取的连接来自于连接池中,而池中的连接根本也还是从DriverManager获取而来

有了数据源这一中间层,就可以实现连接池和分布式事务的管理。

对外呈现DataSource就是类似于DriverManager的一个存在。

DataSource的形式是JNDI (Java Naming Directory Interface)

DataSource是JNDI资源的一种,那么到底什么是JNDI呢

此处不过多解释,可以简单认为JNDI是类似这样一个东西:

一个哈希表,类型为<String,Object>

JNDI的两个最主要操作:bind和lookup。bind操作负责往哈希表里存对象,lookup则根据这个键值字符串往外取对象。

开发人员可以使用键值——也就是一个字符串名称——来获取某个对象。

简言之就是可以给一个对象命名,然后可以通过名称找到这个对象。

数据源的概念在应用程序与数据库连接之间插入了一个中间层,进而可以实现连接池以及事务管理,并且以JNDI的形式,也能够以非常方便的形式使用。

实现

核心架构

关于数据源有以下几个核心的接口

CommonDataSource接口定义了 DataSource、XADataSource 和 ConnectionPoolDataSource 之间公用的方法。

DataSource 是 官方定义的获取 connection 的接口, ConnectionPoolDataSource 是官方定义的从 connection pool 中拿 connection 的接口,XADataSource是定义的用来获取分布式事务连接的接口

也就是分为了三个方向,基本实现,连接池,事务

对于ConnectionPoolDataSource的使用方案应该是下面所示

对于Connection Pool的实现,借助于ConnectionPoolDataSource,进而获取PooledConnection ,然后获取连接,这是一种标准做法

但是有的时候 事情的发展或许并不一定如规划的那般发展

很多的工具类仅仅实现DataSource了,也一并实现连接池以及事务的能力,接口就在那里,我直接实现一个强大的实现类,也没什么问题

DataSource

这是一个工厂对象,用于提供到此 DataSource 对象所表示的物理数据源的连接。

作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。

实现 DataSource 接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API 的命名服务中注册。

DataSource 接口由驱动程序供应商实现。共有三种类型的实现:

  • 基本实现 - 生成标准的 Connection 对象
  • 连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。
  • 分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。

DataSource 对象的属性在必要时可以修改。

例如,如果将数据源移动到另一个服务器,则可更改与服务器相关的属性。其优点在于,由于可以更改数据源的属性,所以任何访问该数据源的代码都无需更改。

通过 DataSource 对象访问的驱动程序本身不会向 DriverManager 注册。

通过lookup操作获取 DataSource 对象,然后使用该对象创建 Connection 对象。

使用基本的实现,通过 DataSource 对象获取的连接与通过 DriverManager 设施获取的连接相同。

数据源的实现必须提供public的无参的构造函数。

API

DataSource只有两个方法(确切的说是一个方法的两个重载版本),用于建立与此 DataSource 对象所表示的数据源的连接。

  • Connection getConnection()
  • Connection getConnection(String username, String password)

小结

DriverManager用于管理驱动程序并且提供数据库的直连,频繁的创建和消耗连接增加系统大量开销,并且将数据库连接直接暴露。

数据源的概念就是为了在应用程序和DriverManager创建的数据库直接连接之间插入一个中间层

借助于中间层,应用程序与数据库的连接两者之间完成了解耦,也能够对数据库的真实连接进行隐藏;

一旦解耦,通过中间层间接调用,类似代理模式,就可以添加更多的服务---连接池以及分布式事务。

数据源相关接口有三个,但是很多是仅仅实现了DataSource接口

而对于连接池本质就是一个容器,负责管理创建好的数据库连接。

连接池与数据源逻辑上是两回事,但是在实现层面的代码中DataSource的实现类往往都具有了连接池以及连接池管理方面的功能。

所以有些时候,DataSource到底是理解成数据源?还是javax.sql.DataSource?还是指的一个实现?还是一个实现了数据库连接池的实现?(经常一个实现了DataSource的并且提供了连接池功能的实现,会被叫做数据库连接池)

应用

Java作为一种广泛使用的开发语言,自然不需要我们自己实现DataSource,一些大厂已经帮我们实现了

比如:DBCP ,C3P0 ,druid

下面的三张图展示了类继承结构,可以看得出来他们实现的接口

目前推荐使用ALI的Druid,http://druid.io/

maven中央仓库: http://central.maven.org/maven2/com/alibaba/druid/

Druid是一个开源项目,源码托管在github上,源代码仓库地址是 https://github.com/alibaba/druid。

Wiki首页:

https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

与其他主流对比

https://github.com/alibaba/druid/wiki/%E5%90%84%E7%A7%8D%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%AF%B9%E6%AF%94

数据库连接池示例

如下一个简单的演示

package jdbc;
import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import org.apache.commons.dbcp2.BasicDataSource;
public class MyDataSource {
  public static void main(String[] args) throws Exception {
      String user = "root";
      String password = "123456";
      String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";
      //1.获取连接
      // Connection conn = getDHCPConnection(user,password,url);
      //Connection conn = getC3P0Connection(user,password,url);
      Connection conn = getDruidConnection(user, password, url);
      String sql = "select * from student limit 0,10";
      //2、获得sql语句执行对象
      Statement stmt = conn.createStatement();
      //3、执行并保存结果集
      ResultSet rs = stmt.executeQuery(sql);
      //4、处理结果集
      while (rs.next()) {
      System.out.print("id:" + rs.getInt(1));
      System.out.print(",姓名:" + rs.getString(2));
      System.out.print(",年龄:" + rs.getInt(3));
      System.out.println(",性别:" + rs.getString(4));
      }
      conn.close();
      stmt.close();
      rs.close();
}
public static Connection getDruidConnection(String user, String password, String url)
throws Exception {
    DruidDataSource ds = new DruidDataSource();
    ds.setUsername(user);
    ds.setPassword(password);
    ds.setUrl(url);
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    return ds.getConnection();
    }
public static Connection getC3P0Connection(String user, String password, String url)
throws Exception {
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    cpds.setUser(user);
    cpds.setPassword(password);
    cpds.setJdbcUrl(url);
    cpds.setDriverClass("com.mysql.jdbc.Driver");
    return cpds.getConnection();
    }
public static Connection getDHCPConnection(String user, String password, String url)
throws Exception {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        Connection connection = dataSource.getConnection();
        return connection;
    }
}

总结

数据源作为DriverManager的替代者,用于获取数据库连接,你应该总是使用DataSource

DataSource是应用程序与数据库连接的一个抽象的中间层,是一个接口

对于DataSource已经有了很多优秀的实现,其中较为突出的为Druid,建议使用,Druid不仅仅提供了连接池的功能还提供了其他比如监控等功能,非常强大。

对于数据源的应用,除了用户名密码url还有其他的一些属性信息,比如最大连接数,建立连接的最大等待时间等,不同的连接池略微有出入,可以查看手册。

对于DataSource的一些实现,经常被叫做数据库连接池,比如Druid官方文档中说“Druid是Java语言中最好的数据库连接池“,本质核心就是DataSource的一个实现类,作为中间层使用,并且基本上都提供了附带的其他的服务,也就是说不仅仅实现了核心建筑,也基于核心之上构建了很多的外围建设。

到此这篇关于Data Source与数据库连接池简介(JDBC简介)的文章就介绍到这了,更多相关数据库连接池Data Source内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JDBC获取数据库连接的5种方式实例

    目录 方式一:直接通过数据库厂商提供的相关驱动 方法二:通过反射的方式来构造Driver对象 方式三:使用DriverManager来替换Driver获取连接 方法四:省略创建Driver对象和注册驱动 方式五:通过配置文件的方式 每种方式迭代的原因 方式五的优点 总结 方式一:直接通过数据库厂商提供的相关驱动 步骤 导入相关驱动(Build Path) 创建Driver类的实例化对象 获取要连接数据库的URL 创建Properties类的实例化对象,将账号和密码封装到该对象中 通过Driver

  • JDBC获取数据库连接由浅入深

    添加MySQL驱动: 不同的数据库厂商都会有自己的实现java.sql.Driver接口的驱动程序,例如mysql的实现就是com.mysql.jdbc.Driver,将mysql-connector-java-版本号-bin.jar添加到相应工程的目录(如果是动态web项目的话,需要将对应的jar包放到WebRoot目录下)下面,右键选择add as library就完成了(如果是使用的eclipse,则是点击build path). 在mysql8.0之后驱动程序的全路径应该是com.mys

  • 详解JDBC的概念及获取数据库连接的5种方式

    目录 一.JDBC概念 二.JDBC获取数据库连接的5种方式 方式一 方式二 方式三 方式四 方式五 一.JDBC概念 Java DataBase Connectivity(Java数据库连接技术) 它是将Java与SQL结合且独立于特定的数据库系统的应用程序编程接口(API-它是一种可用于执行SQL语句的JavaAPI,即由一组用Java语言编写的类与接口所组成) JDBC的设计目的: 它是一种规范,设计出来的主要目的是为了让各个数据库开发商为Java程序员提供标准的数据访问类和接口,使得独立

  • 关于Java中使用jdbc连接数据库中文出现乱码的问题

    目录 一.使用jdbc连接数据库,插入数据库时,数据里的数据显示乱码,为 " ??? " 二.为什么配置了character_set_server = utf8,jdbc连接时就可以不指定编码 三.MYSQL的字符处理机制是怎样的,为什么jdbc不指定编码或者服务端不设置character_set_server=utf8会导致乱码 一.使用jdbc连接数据库,插入数据库时,数据里的数据显示乱码,为 " ??? " 两种解决方案: 1.修改服务端的mysql配置文件,

  • JDBC连接SQL Server数据库实现增删改查的全过程

    目录 前言 JDBC访问数据库的方式 一.连接前准备 1. 环境配置 2. 导入JDBC Driver包 二.连接SQL Server 三.实现增删改查 1. 查询数据 2. 添加数据 3. 修改数据 4. 删除数据 5. 拓展 总结 前言 JDBC的全称是Java数据库连接(Java DataBase Connectivity) ,应用程序通过JDBC连接到数据库,使用SQL语句对数据库中的表进行查询.增加.修改.删除等操作.此文章提供JDBC连接SQL Server的所有步骤,帮助大家实现J

  • Spring 数据库连接池(JDBC)详解

    数据库连接池 对一个简单的数据库应用,由于对数据库的访问不是很频繁,这时可以简单地在需要访问数据库时,就新创建一个连接,就完后就关闭它,这样做也不会带来什么性能上的开销.但是对于一个复杂的数据库应用,情况就完全不同而,频繁的建立.关闭连接,会极大地减低系统的性能,因为对于连接的使用成了系统性能的瓶颈. 通过建立一个数据库连接池以及一套连接使用管理策略,可以达到连接复用的效果,使得一个数据库连接可以得到安全.高效的复用,避免了数据库连接频繁建立.关闭的开销. 数据库连接池的基本原理是在内部对象池中

  • Java数据库连接池之c3p0简介_动力节点Java学院整理

    c3p0是什么 c3p0的出现,是为了大大提高应用程序和数据库之间访问效率的. 它的特性: 编码的简单易用 连接的复用 连接的管理 说到c3p0,不得不说一下jdbc本身,c3p0愿意就是对数据库连接的管理,那么原有的概念还是得清晰:DriverManager.Connection.StateMent.ResultMent. jdbc:java database connective这套API,不用多说,是一套用于连接各式dbms或连接桥接器的api,两个层级:上层供应用方调用api,下层,定义

  • JDBC利用C3P0数据库连接池连接数据库

    JDBC之C3P0数据库连接池,供大家参考,具体内容如下 1 首先在src中创建c3p0-config.xml 配置文件,文件中内容如下(首先下载C3P0.jar工具包 并放入项目环境变量中) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xml> <c3p0-config> <!--下面四个是数据库连接必须需要的东西 --> <named-config nam

  • Java数据库连接池之DBCP浅析_动力节点Java学院整理

    一. 为何要使用数据库连接池 假设网站一天有很大的访问量,数据库服务器就需要为每次连接创建一次数据库连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机. 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正式针对这个问题提出来的.数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个. 数据库连接池

  • eclipse3.2.2 + MyEclipse5.5 + Tomcat5.5.27 配置数据库连接池

    now begin: step 1: 建立数据库连接池. 1. 从Tomcat的主页上下载Tomcat5.5.27,推荐绿色版(zip),不用为重做系统而发愁. 2. 下载Tomcat5.5.27的admin包,解压缩后覆盖Tomcat5.5.27的根目录. 3. 在Tomcat5.5.27的根目录下conf文件夹里的tomcat-users.xml里, </tomcat-users>之前加上一行 <user username="admin" password=&qu

  • SpringBoot2.0 中 HikariCP 数据库连接池原理解析

    作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC Connection Pool.Druid 等,不过最近最火的是 HiKariCP. HiKariCP 号称是业界跑得最快的数据库连接池,自从 SpringBoot 2.0 将其作为默认数据库连接池后,其发展势头锐不可当.那它为什么那么快呢?今天咱们就重点聊聊其中的原因. 一.什么是数据库连接池

  • Java中几种常用数据库连接池的使用

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.如下图所示: 二.使用数据库连接池优化程序性能 2.1.数据库连接池的基本概念 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性

  • 使用springboot不自动初始化数据库连接池

    目录 springboot不自动初始化数据库连接池 简介 解决方案 记录下spring boot关于数据库连接池的一个小坑 application.properties配置 先找到这个类 在下面的源码中打个断点 启动项目 springboot不自动初始化数据库连接池 简介 有时候我们想自己动态的初始化数据库连接池,但是springboot 的@SpringBootApplication注解会自动去初始化数据库连接池,不配置的话会启动失败,如下提示 Exception encountered du

  • SpringBoot整合Druid实现数据库连接池和监控

    目录 1.Druid的简介 2.创建SpringBoot项目与数据表 2.1 创建项目 2.2 创建数据表 3.Druid实现数据库连接池 3.1 Druid的配置 3.2 创建实体类(Entity层) 3.3 数据库映射层(Mapper层) 3.4 业务逻辑层(Service层) 3.5 控制器方法(Controller层) 3.6 显示页面(View层) 4.Druid实现监控功能 1.Druid的简介 Druid是Java语言中使用的比较多的数据库连接池.Druid还提供了强大的监控和扩展

  • SpringBoot4.5.2 整合HikariCP 数据库连接池操作

    目录 SpringBoot4.5.2 整合HikariCP 数据库连接池 引入 application.yaml 输出 HikariCP连接池及其在springboot中的配置 主要配置如下 SpringBoot4.5.2 整合HikariCP 数据库连接池 Spring Boot 2.+默认使用的就是连接池HikariCP 所以,只要引入相关包即可 引入 <dependency> <groupId>org.springframework.boot</groupId>

随机推荐