对比(5.1.48VS8.0.16)getConnection、isValid

一、驱动以及目录结构

官网地址:https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/

1.1 驱动对比

5.1.48 引入驱动时名称为:com.mysql.jdbc.Driver

8.0.16 引入驱动时名称为:com.mysql.cj.jdbc.Driver ,如果 驱动还配置 5.x 的版本,也没有问题,只是会如下提示:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

在这里插入图片描述
但是还是会自动 切换成 新的驱动,原因如下,主要是做了代码兼容,让原先的Driver继承了com.mysql.cj.jdbc.Driver ,然后在
在这里插入图片描述
然后com.mysql.cj.jdbc.driver 里面的 静态块 进行注册:

public 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!");
        }
    }
}

在DriverManager 类里面的 通过了SPI 进行了注册和初始化:

/**
     * Load the initial JDBC drivers by checking the System property
     * jdbc.properties and then use the {@code ServiceLoader} mechanism
     */
    static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }

在这里插入图片描述在这里插入图片描述

1.2 目录结构对比

5.1.X的源码目录结构和 8.0.16 的代码结构也有很大的变化,这里就不贴图了,感兴趣的自己去下载源码看,源码地址:gitHub地址
这里对比一下 对JDK 的要求:
在这里插入图片描述
此外,JDBC 版本和 JDK 对应的关系如下:

一、JDBC 1.0 随JDK1.1发布;
二、JDBC 2.0 随JDK1.2 和 JDK1.3 发布
JDBC 2.0 和 JDBC 2.1 API 被分入两个包:
java.sql 包(包括核心 API;它是 JDBC 1.22 API 的增强)
javax.sql 包(可选的包,用于支持连接池、分布式事务及其他类似的高级功能)。
三、JDBC3.0 随JDK1.4发布
四、JDBC 4.0 随 JDK1.6 发布
五、JDBC4.1 随 JDK1.7 发布
六、JDBC4.2 随 JDK1.8 发布

二 getConnection流程对比

这里主要是分析的正常流程:

2.1 5.1.48版本getConnection

在这里插入图片描述
大致流程:

  1. 判断url 是否为空,为空泽抛出异常
  2. 判断url 是否以"jdbc:mysql:loadbalance://" 开头,是则创建对应的负载均衡的connet,否则继续步骤3
  3. 判断url是否以“jdbc:mysql:replication://” 开头,是泽创建对应的Replication
    的connect,否则继续
  4. 对URL 进行 解析,转换成Properties 以便后面使用
  5. 判断NUM_HOSTS 是否 >1 ,是 则 走connectFailover 流程,否则继续
  6. 判断是否是 jdbc4, 是支持jdbc4的,那就先 通过构造函数实例JDBC4Connection
  7. JDBC4Connection 继承了 ConnectionImpl,这里 会 createNewIO(false); 进行和mysql server进行创建connection
  8. 通过StandardSocketFactory 创建 socketFactory,使用标准的 TCP/IP sockets (the
    standard) 进行socket 连接
  9. 通过BufferedOutputStream 进行 确定,这样一个connection就创建完成.

2.2、8.0.16版本的getConnection流程

在这里插入图片描述
大致流程如下:

  1. 判断url 是否为空,如果为空,抛出异常
  2. 通过正则表达式验证 URL的开头是否符合规定的,这里 通过枚举列出来,5.1.48 是逐个判断,个人感觉8.0.X的 代码结构相关整洁一些,类型如下,官方给出解释,不同的数据库用错驱动比较常见,比如用的ServerSQL 的数据库,用的mysql 的驱动在这里插入图片描述
  3. 对URL 进行拼接,拼接玩,用此链接作为Key,从缓存里面获取对应的ConnectionUrl 实例
  private static final LRUCache<String, ConnectionUrl> connectionUrlCache = new LRUCache<>(100);

在这里插入图片描述
4. 获取到了就直接返回,获取不到就 通过 Class.forName 进行构造
5. 拿到ConnectionUrl 之后,根据对应的Type 进行和 mysql Server 创建Connection
6. 先对各类参数进行初始化,然后 createNewIO(false);
7. 这里通过 TCP/IP sockets (the standard) 开始进行连接, 建立之后 ,连接的状态是
:unauthenticated user,还没去确认,等待client 端确认.
8. 这里相对 5.1.48 做了进一步的细化, 创建了一个 protocol , 明确了:物理连接仅负责 I / O流,而 protocol 负责创建 session ,以及 内部认证,protocol 对 读取和发送消息也进行了封装.,这里 protocol.connect 进行确认,正式创建连接

三、isValid 流程对比

两个版本的isValid ,都是拿到连接之后,通过socket 发送一个 a ping command给到 mysql Server ,然后读取对应的消息,如果获取到的是 java.io.EOFException ,说明此connection 已经断开,抛出异常, 两个版本的大致流程基本一样,这里就不贴对比了,直接贴一下两个的大致流程路径:
在这里插入图片描述

四、升级遇到的坑

4.1 SQL String cannot be empty

Error updating database. Cause: java.sql.SQLException: SQL String cannot be empty

这个是由于 原先的5.x 没有对 非空校验,只是校验了 是否为null,而8.x 多了一个校验.
在这里插入图片描述

4.2 Date 类型 问题

数据库里面是 Date(对应 java.sql.Date) 类型,查询的时候,传入的是 Date(java.util.Date) 类型,5.1.48 可以查询到,升级之后查询不到,主要原因是 8.X 的版本,在时间转换时加了 时区 进去,而5.x没有
解决办法: 服务器的 时区和 mysql服务器要一致
在这里插入图片描述

4.3 timestamp、datetime类型

在 5.1.48 的 版本里面 ,
如果 把表里的类型 为 timestamp,datetime 类型 直接转为 String 类型,后面有一个 .0 毫秒格式,如下:

2020-04-19 07:34:52.0

而在8.0.16 里面直接 转为:

2020-04-19 07:34:52

格式有细微的差别

五、对比总结

5.1 getConnection 小结

  1. 8.0.16 对整个代码的结构进行了调整, 原先 5.1.x 很多的if …else 这类分支 ,8.0.16版本 通过正则 匹配 过滤掉不符合 规范的url ,再 通过 枚举 方式 匹配对应的 情况,这样代码更加简洁, 也更加直接,不符合的url 直接返回而不需要到创建的时候才发现不符合,效率更高.

  2. 8.0.16 里面设置了一个 缓存,key 为拼接好的URL ,value 对对应的connectionUrl, 创建连接时,每次的url一样就不用每次都通过构造函数来进行创建 ,这里进行了一定的优化,创建的速度更快

  3. 在 和mysql server 进行创建 连接时,都是创建socket 连接,但8.0.16 把很多的代码进行了重新整合,引入了一个 protocol 辅助类,对一些读写 方法 都重新封装,层次更加清晰了一些,也对校验进行了一定程度的增强.

5.2 其他对比

  1. 8.0.16 依赖 JDBC 4.2 ,所以要求JDK1.8

  2. 8.0.16 版本修复了一些bug 和对一些方法进行了整合,详见:mysql-connector-java 官方描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直打铁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值