java加载mysql驱动_Java 加载数据库驱动(JDBC)

本文探讨了Java加载MySQL驱动时使用Class.forName("com.mysql.jdbc.Driver")的疑惑。通过分析源码,解释了该语句实际上将驱动注册到DriverManager,以便能够连接数据库。文章建议虽然显示注册驱动可能使代码更清晰,但在MySQL JDBC驱动中,由于类加载过程已自动完成注册,因此直接使用Class.forName()是合适的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2ff34e647e2e3cdfd8dca593e17d9b0a.png

前言

之前,对Class.forName("com.mysql.jdbc.Driver");这条动态加载JDBC驱动感觉很疑惑,故有了这篇短文。

一、使用JDBC连接MySQL

首先,来看一下正常使用Java操纵MySql的简单代码逻辑。

1

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

34

35

36

37

38public static boolean connectionMySqlDemo() {

Connection conn = null;

try {

// 1、动态加载mysql驱动

Class.forName("com.mysql.jdbc.Driver");

// 2、连接数据库

conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?"

+ "user=root&password=1234&useUnicode=true&characterEncoding=UTF8");

// 3、声明一个Statement 用来执行sql语句

Statement stmt = conn.createStatement();

// 4、执行sql语句

stmt.executeUpdate("create table student(no_id char(20),name varchar(20),primary key(no_id))");

int result = stmt.executeUpdate("insert into student(no_id,name) values('1','fxleyu')");

if (result > 0) {

ResultSet rs = stmt.executeQuery("select * from student");

while (rs.next()) {

System.out.println(rs.getString(1));

}

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} finally {

// 5、关闭数据库

if (conn != null) {

try {

conn.close();

return true;

} catch (SQLException e) {

e.printStackTrace();

}

}

}

return false;

}

在上述代码中,动态加载数据库驱动那条语句感觉独立于其余代码逻辑。感觉缺少其并无关系(当然缺少了会在链接数据库时报java.sql.SQLException: No suitable driver found for)。

二、疑惑

上述代码很容易理解,除了如下Class.forName("com.mysql.jdbc.Driver");。

正常理解,该语句只是加载把com.mysql.jdbc.Driver加载到JVM中,没不会产生特殊作用。

阅读com.mysql.jdbc.Driver代码,可以发现其中的隐含逻辑。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23public class Driver extends NonRegisteringDriver implements java.sql.Driver {

//

// Register ourselves with the DriverManager

//

static {

try {

java.sql.DriverManager.registerDriver(new Driver());

} catch (SQLException E) {

throw new RuntimeException("Can't register driver!");

}

}

/**

* Construct a new driver and register it with DriverManager

*

* @throws SQLException

* if a database error occurs.

*/

public Driver() throws SQLException {

// Required for Class.forName().newInstance()

}

}

原来该类中有静态代码库,其加载到JVM时,会执行该静态代码库。

而该代码块会把该类的对象实例自注册到DriverManager中。

如此第一部分中的第二步就很容易理解了。

1

2

3// 2、连接数据库

conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?"

+ "user=root&password=1234&useUnicode=true&characterEncoding=UTF8");

其就是可以根据String来获得上述加载的驱动,从而可以正常访问数据库。

三、余以为

代码的逻辑很重要,而Class.forName("com.mysql.jdbc.Driver");单独来看只是一条孤立的语句。

没有和上下文代码产生显示的关联,这就导致了余在前言中的疑惑。

故,使用Class.forName("com.mysql.jdbc.Driver");来动态注册驱动,会对当前代码逻辑产生不利影响。

正常的逻辑,Class.forName方法就是加载一个指定类,并对该类做一些初始化工作(使用静态代码库),

其不应该做一些其它逻辑,例如动态注册驱动。

如果需要注册驱动时,应该让用户自己使用DriverManager.registerDriver(new com.mysql.jdbc.Driver());来显示注册。

这样代码逻辑会很清晰。

但在这里使用显示注册并不合适。因为当new com.mysql.jdbc.Driver()的动作中,就有类的加载过程。在该过程中,已经把该驱动加载到了DriverManager的列表中。而有显示的注册了一次,故DriverManager的列表会有两个com.mysql.jdbc.Driver实例。也就是说,MySql的jdbc并不适合用来进行显示加载。

当然,也许使用Class.forName("com.mysql.jdbc.Driver");有MySql团队自己的考虑,而我当前视野并没有看到其好处。

四、结束

Talk is cheap, show me the code. 当对某些代码逻辑有疑问时,不妨查看一下相关源码,就会豁然开朗。自勉。P.S. 第三部分的余以为灵感借鉴于“余晟以为”微信公众号,很喜欢他那句“我是这么以为的,当然你也可以那么以为”。

参考

1、使用源码下载路径 http://101.96.8.142/dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.40.tar.gz

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值