说到JDBC我们首先应该想到Java中的13个规范,里面就其中一条规范就是JDBC,哪它究竟是什么又有什么用呢?
我们先看一下百度百科怎么描述
简单的说就是Java连接数据库的方法,但是我们都知道Java语言是由Oracle公司开发和维护的,但众多数据库又是由不同的公司进行开发的,底层结构不同,所以Java语言无法直接连接数据库,这时就出现了JDBC规范。
JDBC在Java中就体现为接口,既然我无法直接连接到数据库,那我就制定一个连接数据库的规范(接口),各个数据库厂商如果支持Java语言连接到自己的数据库那你就必须在Java中的JDBC规范下自己写支持连接的代码(数据库厂商自己写一个类实现JDBC规范中的接口,然后在这个类中编写支持Java连接到自己数据库的实现代码,我们通常将这样的代码叫数据库驱动)。
这样我们在使用Java连接各个数据库时,只需要下载对应的数据库驱动,就能连接到数据库了。
以连接MySQL数据库为例,我们来看看JDBC规范中的接口和MySQL驱动中的实现。
JDBC中的Driver,所有支持Java连接的驱动类都要实现它
先下载MySQL的数据库驱动的jar包,添加到我们的项目中,如果是使用maven,直接使用maven导包
我们打开这个包,找到这个包com.mysql.cj.jdbc目录下的Driver类,我们可以看到这个类实现了Java中的原生接口 java.sql.Driver (即上述的JDBC规范的Driver接口)。
这样我们就能在Java中使用MySQL数据库驱动连接到MySQL数据库了。
在使用Java代码连接到数据库时会看到不同的实现方式,为什么会有不同的方式,这样做的理由和好处是什么,接下来让我们一起来看看吧。
1、方式一
在使用Java连接到数据库时使用的数据库驱动本质就是一个实现了JDBC规范的Java类,我们使用用这个驱动就能连接到对应的数据库了,那该怎么使用呢,既然是一个Java类那我们自然想到的是new
public void connection1() throws SQLException {
// 1.获取驱动,这个Driver类就是MySQL驱动类
Driver driver = new Driver();
// 2.建立连接
Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "123456");
// jdbc:mysql:// 表示协议,通过jdbc的方式连接mysql
// localhost 表示要连接mysql所在服务器的ip地址,localhost 表示本机
// 3306 表示mysql监听的端口号,即要访问的mysql所在服务器的端口号
// book 要访问的数据库
String url = "jdbc:mysql://localhost:3306/book?characterEncoding=utf8&serverTimezone=UTC";
Connection connection = driver.connect(url, properties);
// 3.获取数据库操作对象
Statement statement = connection.createStatement();
// 4.执行sql
ResultSet resultSet = statement.executeQuery("select * from t_book");
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + " "
+ resultSet.getString(2) + " "
+ resultSet.getString(3));
}
// 5.关闭连接
statement.close();
connection.close();
}
2、方式二
数据库驱动是由第三方提供的jar包,在方式一中我们静态的加载驱动类,这样做耦合度高、依赖性强、灵活度差。所以我们采用反射的方式来获取驱动类。
public void connection2() throws Exception {
// 1.获取驱动
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
// 2.获取连接
Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "123456");
String url = "jdbc:mysql://localhost:3306/book?characterEncoding=utf8&serverTimezone=UTC";
Connection connection = driver.connect(url, properties);
System.out.println(connection);
}
3、方式三
在Java中有专门管理数据库驱动的类DriverManager,它是由Java本身提供的,在使用它的时候我们要在获取驱动后再注册驱动,然后在获取连接
public void connection3() throws Exception {
// 1.获取驱动
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
/**
* 2.注册驱动
* 在 DriverManager 驱动管理类中注册 数据库驱动类,就是将该驱动存放到数据库容器中
* 在使用 DriverManager.getConnection() 获取数据库连接时会 遍历存放数据库驱动的容器
* 尝试连接数据库
*/
DriverManager.registerDriver(driver);
String url = "jdbc:mysql://localhost:3306/book?characterEncoding=utf8&serverTimezone=UTC";
String user = "root";
String password = "123456";
// 3.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
}
为什么在注册驱动后就可以直接获取连接了呢?
在 DriverManager.registerDriver(driver); 底层是将注册的数据库驱动添加到一个容器中
我们进入到 registerDriver(driver, null);源码中
我们再查找 registeredDrivers 是什么,发现它就是一个存放数据库驱动的list列表
那这个存放数据库驱动的列表有什么用呢,为什么将数据库驱动注册到列表中就可以获取连接了呢?我们再查看
DriverManager.getConnection(url, user, password); 的源码。
可以发现获取连接最后返回的是
我们再进入它的源码中查看,可以看到核心如下图
可以看到对 registeredDrivers 进行了遍历,这不就是上面提到的存放数据库驱动的容器嘛
我们再看
Connection con = aDriver.driver.connect(url, info);
aDriver 是 DriverInfo 类,我们进入这个类可以发现它有一个Driver属性
那这条语句就表示由数据库驱动容器遍历出来的驱动尝试连接到对应的数据库
这里我们就理解了为什么把数据库驱动注册后就可以由DriverManager.getConnection直接获取连接了
4、方式四
这里我们直接在调用反射后就直接获取连接了,为上面没有实例化和注册驱动呢
我们进入MySQL的驱动类看看
可以看到在开始就有一个静态代码块,里面进行了数据库驱动的注册
在类进行初始化时会加载当前类中的静态代码块所以在使用反射加载这个类时就运行了这个静态代码块注册了这个驱动类,所以不用进行实例化和加载驱动就能直接获取连接了