一、什么是JDBC?
JDBC,即
Java Database Connectivity
,java数据库连接。是一种用于执行SQL语句的Java API,它是Java中的数据库连接规范。这个API由java.sql.*,javax.sql.*
包中的一些类和接口组成,它为Java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问
二、JDBC工作原理
JDBC 为多种关系数据库提供了统一访问方式,作为特定厂商数据库访问API的一种高级抽象,它主要包含一些通用的接口类
下面是我画的一张有关JDBC访问数据库层次结构的图:
可以看到,我们程序员在开发JavaEE应用的时候,通过调用Sun公司提供给我们的JDBC相关API,就可以切访问数据库的JSBC驱动程序,继而通过驱动来加载数据库
JDBC优势:
- Java语言访问数据库操作完全面向抽象接口编程
- 开发数据库应用不用限定在特定数据库厂商的API
- 程序的可移植性大大增强
三、使用JDBC连接MySQL数据库【✔】
1、安装对应数据驱动包
那有同学就问了,数据驱动包是什么?
💬 对于数据驱动包而言,其实就是上面我所说到的各个【数据库厂商】所提供给我们的JDBC驱动程序,因为只有数据库厂商那边提供给了我们加载数据库的驱动,我们才能去获取到数据库中的数据表然后进行CRUD等操作
- 这样说呢可能还不是很好理解,我们可以通过画图来帮助理解,知道了JDBC的工作原理后,我们还要去了解什么去驱动包
接下去就要去下载这个驱动包,去哪里下呢?当然是官网!
- 但是呢,官网很麻烦,你要一个个地去找,不知道要下那个才好,下面是MySQL的官网的驱动下载处,很好找。但若是你用的是Oracle数据库的话,就会很麻烦了,因为它们这家公司很大,产品也很多,所以官网中会很很多东西,你很难去找到自己想要的驱动程序
难道这就没办法了吗?要一个个找吗😥当然有,那就是我们心爱的【Maven】
- 对于Maven而言,学Java的同学一定不陌生,它是一个 “中央仓库”,Maven 作为 Java 项目管理工具,它不仅可以用作包管理,还有许多的插件,可以支持整个项目的开发、打包、测试及部署等一系列行为,简直是居家旅行、
杀人灭口必备良药! - 咳咳,然后我们就可以去下载MySQL对应的驱动包了,按照下图指示来即可
- 点进去之后就可以选择对应的驱动包版本了,但是这里在选择的时候要注意了,需要和你MySQL安装的版本一致才可,我的MySQL是
5.7
的,所以这里大版本不能变,要选择5.1开头的,后面的小版本没关系;当然如果你的MySQL是8.x
版本的,你就要选择8开头的驱动包了
- 点进去之后我们看到有个
jar
,点一下它,你就可以拥有一个MySQL相关的驱动包了,就和我们平常使用的.rar
、.zip
压缩包没什么区别,就是Java的压缩包以.jar
结尾
- 下载好了之后就是这个样子的
2、将jar包导入项目中
现在我们有了这个jar后,就要把它用起来
- 那现在我们去新建一个项目,然后把这个包导进来,不过在此之前要新建一个名为
lib
的目录,它是library库
的缩写,当然你也可以写其他的名称
- 然后右键这个目录选择【添加为库...】
- 此时这个MySQL的驱动库就导入到我们的项目中了
3、编写代码连接数据库【⭐】
加载完MySQL的驱动包之后,我们就可以使用一些API去操作数据库了,准备好了吗,发车了:car:
1️⃣ 创建数据源
👉首先第一点,要连接数据库的话,我们就要知道这个数据库在哪里
- 这里我会介绍两种方式,一个是通过
DataSource
(数据源)对象获取,另一种则是通过DriverManager
(驱动管理类)的静态方法获取,不过重点在于第一种
①DataSource
(数据源)对象获取
- 下面是创建数据源的相关代码,我使用到了Java中的向上转型和向下转型,不是很清楚的同学可以先去了解一下
DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("xxxxxxxxxxx");
- 也就是这一句我使用到了向上转型,
DataSource
是Java中的一个接口,MysqlDataSource
则是它的实现类,下面这种便是很典型的使用接口来实现==向上转型==
DataSource dataSource = new MysqlDataSource();
- 然后下面的
setURL()
、setUser()
、setPassWord()
都是【MysqlDataSource】这个接口实现类中的一些方法,但是由于向上转型后父类无法去调用子类独有的方法,所以我们还要去进行一个==向下转型== - 通过去进行一个强制类型转换就可以做到,此时我们便能调用到实现类中的方法了
((MysqlDataSource)dataSource).setURL(...) ((MysqlDataSource)dataSource).setUser(...) ((MysqlDataSource)dataSource).setPassWord(...)
💬 那有同学问:为什么要这么麻烦呢?转上又转下?直接使用MysqlDataSource
不就好了
- 道理确实是这样,如果我们直接将代码写成下面这样子,那么就可以直接去调用这个类中的方法了,无需再去做一个向下转型,但是这却隐藏着巨大的隐患...
MysqlDataSource dataSource1 = new MysqlDataSource();
可能没有真正做过开发的同学还体会不到这一点,因为我们在设计一些接口、类的时候始终要遵循【高内聚 · 低耦合】的思想,==即类的内部各个方法之间要紧密关联,但类与类之间不要产生太大的依赖==
- 光这么说可能说不太清楚,有兴趣的同学可以先去了解一下高内聚 · 低耦合
- 因为在上面我们使用的是【MysqlDataSource 】,所以在程序的其他方法中,我们可能也需要使用到这个类去做一个接受,就是因为这种==高内聚==的原因,导致了【MysqlDataSource 】被大量地进行扩散,此危害性就在于后续我们的项目要更换数据库的就需要改动很多的代码,加大了工作量!!!
void func1(MysqlDataSource dataSource1){} void func2(MysqlDataSource dataSource2){}
然后呢我们再来说说为什么要去调用这些API
- 首先的话是
serURL()
,对于【URL】来说,学习过HTTP协议的同学应该是非常熟悉,对于浏览器发送的HTTP请求中第一行就是URL,它叫做 统一资源定位符,也就是我们日常生活中所说的【网址】,描述了互联网上唯一一个资源的位置
我们可以来解读一下这个所传入的这个URL
- 那对于下面的
User
和PassWord
就很清楚了,就是用户名和密码,MySQL用户名固定就是【root】,密码的话就是你安装MySQL的时候手动设置的密码。 - 虽然很多数据库是根据用户名和密码来进行认证的,但是有些数据库,向
SQLite
就不是用的这个进行认证,所以这就是为什么这些方法均在【MysqlDataSource 】里的原因了,每个数据库都有它们独特的验证方式,所以我们在使用不同数据库时加载不同的驱动包即可
2️⃣ 和数据库建立网络连接
在上面呢,我们只是进行了数据源的创建操作,只是描述了服务器在哪,并没有真正得进行访问,那现在我们所要做的操作就是【连接】,通过网络去进行一个通信
- 然后我们就可以通过【DataSource】接口中一个方法叫做
getConnection()
这个方法去建立一个网络连接,它会返回一个实例为【Connection】的对象,不过从下图可以看到很多种类的Connection,那我们选哪个呢? - 这里要注意,选择这个
java.sql
的,这才是我们想要的Connection
Connection connection = dataSource.getConnection();
- 要注意这里了连接(Connection),而不是链接(Link),对于连接而言并不复杂,因为只有这么一句代码,因为在网络中客户端和服务器之间要去建立一个连接,就只是找个地方记录下而已,并不需要非常繁琐的步骤
- 而且还要注意的是这个
getConnection()
还需要去处理异常,一般来说像我们在进行文件读取、数据库操作都是需要去捕获这个异常的,这里我直接【throws】了,你也可以【try..catch】,如果异常还不是很了解的同学再去学习一下
打个比方说,就像民政局登记结婚一样,只是找个地方登记一下我们结婚了,也无需像婚礼那样大动干戈
②DriverManager
(驱动管理类)的静态方法获取
讲了这么多,别忘了我们只讲了一种数据库连接方式,别忘了还有第二种,那就是使用
DriverManager
- 但是我并不打算讲解这种方式,因为它需要借助我们在JavaSE中所学习的【反射】,但是对于反射来说其实是不属于常规的编程手段,不在特殊的情况下还是不推荐使用的。你可以在看了下面这两种连接方式的区别后再来回顾
// 加载JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); // 创建数据库连接 Connection connection = DriverManager.getConnection(url);
区别:
- DriverManager类来获取的Connection连接,是无法重复利用的,每次使用完以后释放资源时,通过connection.close()都是关闭物理连接。
- DataSource提供连接池的支持。连接池在初始化时将内置了【数据库连接池】,这些连接是可以复用的,每次使用完数据库连接,释放资源调用connection.close()都是将Conncetion连接对象回收
💬 可能有同学对这个【数据库连接池】不太理解,我们这里来讲一讲(doge)
- 在Java中呢我们学习过很多的池,比方说:String字符串常量池、进程池、线程池、内存池,它们都是池
- 那谈到池这个东西我们就想到了【池塘】,那假设呢你现在是个妹子,长得好看,又有才华,所以追求者就与很多,但是呢同一时间只能谈一个对象,但是你又不想拒绝其他的追求者,因为如果当前这个对象谈到后面谈不来的话,就需要再换一个,此时的话就会有很多的成本,因为需要重新培养感情
- 那于是你就想了一个很不错的办法来提高效率,那就是【养鱼🐟】
- 怎么养鱼呢?也就是在和A谈对象的同时和B搞暧昧,同时培养感情基础,一旦你和A分手了,就可以立马和B在一起,此时大大提高了效率,那么这个B就被亲切地称之为【备胎】
- 但是你的备胎可能还不只B这一个,可能还有CDEFGHI.....,此时它们就构成了一个“备胎池”,若是B不合适了还可以换其他人上位,而且呢,这个时候A也还在池子里,若是你和其他人都不和的时候,又想到A了,此时你就可以再和A在一起
当然,上面只是举一个小小的案例,现实生活中我们不提倡这么去做~ 但是在计算机里这种做法还是很常见的,可以了解一下