什么是JDBC
# 00.什么是JDBC
Java为关系数据库定义了一套标准的访问接口:JDBC(Java Database Connectivity),本章我们介绍如何在Java程序中使用JDBC。
本文只讲解JDBC技术,读者应了解什么是数据库和MySQL后再来学习,并提前安装好MySQL。
# JDBC介绍
什么是JDBC?JDBC是Java DataBase Connectivity的缩写,它是Java程序访问数据库的标准接口。注意,只是接口而已,并没有具体的实现类。
使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而 JDBC 接口则通过 JDBC 驱动来实现真正对数据库的访问。
为什么要这样做呢?首先数据库产品有很多,例如MySQL,Oracle,DB2....等等,而且连接方式都各有差异;为此,Java直接定义了一套接口,然后各个数据库厂商分别实现这个接口,并提供jar包(也叫JDBC驱动),这样我们就可以直接使用一套代码,连接不同的数据库产品。
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
│ ┌───────────────┐ │
│ Java App │
│ └───────────────┘ │
│
│ ▼ │
┌───────────────┐
│ │JDBC Interface │←─┼─── JDK
└───────────────┘
│ │ │
▼
│ ┌───────────────┐ │
│ MySQL Driver │←───── Oracle
│ └───────────────┘ │
│
└ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ┘
▼
┌───────────────┐
│ MySQL │
└───────────────┘
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
一个MySQL的JDBC的驱动就是一个jar包,它本身也是纯Java编写的。我们自己编写的业务代码只需要引用Java标准库提供的java.sql包下面的相关接口,由此再间接地通过MySQL驱动的jar包通过网络访问MySQL服务器,所有复杂的网络通讯都被封装到JDBC驱动中,因此,Java程序本身只需要引入一个MySQL驱动的jar包就可以正常访问MySQL服务器。
使用JDBC的好处
- 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发,使用一套Java代码就可以操作所有的关系型数据库。
- Java程序编译期仅依赖java.sql包,不依赖具体数据库的jar包;
- 可随时替换底层数据库,访问数据库的Java代码基本不变。
# 使用JDBC的好处
- 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发,使用一套Java代码就可以操作所有的关系型数据库。
- Java程序编译期仅依赖java.sql包,不依赖具体数据库的jar包;
- 可随时替换底层数据库,访问数据库的Java代码基本不变。
# 数据库准备
为了后续的学习,需要准备一点数据。这里我们用一个脚本创建数据库和表,然后插入一些数据:
-- 创建数据库learjdbc:
DROP DATABASE IF EXISTS learnjdbc;
CREATE DATABASE learnjdbc;
-- 创建登录用户learn/口令learnpassword
CREATE USER IF NOT EXISTS learn@'%' IDENTIFIED BY 'learnpassword';
GRANT ALL PRIVILEGES ON learnjdbc.* TO learn@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
-- 创建表students:
USE learnjdbc;
CREATE TABLE students (
id BIGINT AUTO_INCREMENT NOT NULL,
name VARCHAR(50) NOT NULL,
gender TINYINT(1) NOT NULL,
grade INT NOT NULL,
score INT NOT NULL,
PRIMARY KEY(id)
) Engine=INNODB DEFAULT CHARSET=UTF8;
-- 插入初始数据:
INSERT INTO students (name, gender, grade, score) VALUES ('小明', 1, 1, 88);
INSERT INTO students (name, gender, grade, score) VALUES ('小红', 1, 1, 95);
INSERT INTO students (name, gender, grade, score) VALUES ('小军', 0, 1, 93);
INSERT INTO students (name, gender, grade, score) VALUES ('小白', 0, 1, 100);
INSERT INTO students (name, gender, grade, score) VALUES ('小牛', 1, 2, 96);
INSERT INTO students (name, gender, grade, score) VALUES ('小兵', 1, 2, 99);
INSERT INTO students (name, gender, grade, score) VALUES ('小强', 0, 2, 86);
INSERT INTO students (name, gender, grade, score) VALUES ('小乔', 0, 2, 79);
INSERT INTO students (name, gender, grade, score) VALUES ('小青', 1, 3, 85);
INSERT INTO students (name, gender, grade, score) VALUES ('小王', 1, 3, 90);
INSERT INTO students (name, gender, grade, score) VALUES ('小林', 0, 3, 91);
INSERT INTO students (name, gender, grade, score) VALUES ('小贝', 0, 3, 77);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在控制台输入mysql -u root -p
,输入root
口令后以root
身份,把上述SQL贴到控制台执行一遍就行。如果你运行的是最新版MySQL 8.x,需要调整一下CREATE USER
语句。
# 下载依赖
前面我们讲了Java程序要通过JDBC接口来查询数据库。JDBC是一套接口规范,它在哪呢?就在Java的标准库java.sql
里放着,不过这里面大部分都是接口。接口并不能直接实例化,而是必须实例化对应的实现类,然后通过接口引用这个实例。那么问题来了:JDBC接口的实现类在哪?
因为JDBC接口并不知道我们要使用哪个数据库,所以,用哪个数据库,我们就去使用哪个数据库的“实现类”,我们把某个数据库实现了JDBC接口的jar包称为JDBC驱动。
因为我们选择了MySQL 5.x作为数据库,所以我们首先得找一个MySQL的JDBC驱动。所谓JDBC驱动,其实就是一个第三方jar包。
可以从我的GitHub仓库里下载 jar包(mysql-connector-java-8.0.27.jar):
Gitee:lib · /LearnJavaEE - Gitee (opens new window)
GitHub:LearnJavaEE/lib at master · Peter-JXL/LearnJavaEE (opens new window)
我们可以去一个叫做Maven仓库的地方下载:Maven Repository: mysql » mysql-connector-java » 8.0.27 (opens new window)
下载后,记得添加到IDE的依赖。
如果你会Maven,可以这样添加依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
2
3
4
5
6
注意到这里添加依赖的scope
是runtime
,因为编译Java程序并不需要MySQL的这个jar包,只有在运行期才需要使用。
如果把runtime
改成compile
,虽然也能正常编译,但是在IDE里写程序的时候,会多出来一大堆类似com.mysql.jdbc.Connection
这样的类,非常容易与Java标准库的JDBC接口混淆,所以坚决不要设置为compile
。
# 总结
JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。开发者可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
举个例子,我们定义一个Person接口,然后Worker实现这个接口:
Person p = new Worker();
p.eat();
2
上面我们用Person类型接受了worker类型的变量,在执行具体的方法的时候,执行的是Worker类型里的方法。
JDBC也是一样的,JDBC只定义了一套接口,具体实现类由各个数据库厂商实现,调用方法的时候也是调用具体实现类的方法。