MySQL Connector/J 8.0

前言

MySQl是现在互联网中使用最广泛的数据库。Connector/J则是MySQl为Java程序客户端应用程序提供的JDBC连接方案。

逻辑结构概述

Connector其大致调用逻辑如下图所示

DriverManager

我们最原始的获取Mysql连接的方式如下

  Class.forName("com.mysql.cj.jdbc.Driver");
  //或者设置环境变量jdbc.drivers让DriverManager帮忙调用Class.forName
  //System.setProperty("jdbc.drivers","com.mysql.cj.jdbc.Driver");
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?logger=Slf4JLogger", "sa", "sa");

通过阅读DriverManager的源码可以发现,它是一个Driver管理器,其获取Driver途径主要为registerDriver方法。

  1.  com.mysql.cj.jdbc.Driver 在static模块中调用registerDriver
  2. DriverManager加载时会解析环境变量jdbc.drivers声明的class,然后加载
  3. 当执行conn = DriverManager.getConnection进行Driver的选择
private static Connection getConnection(
        String url, java.util.Properties info, Class<?> caller) throws SQLException {
       ....
 
        for(DriverInfo aDriver : registeredDrivers) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if(isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);
                    if (con != null) {
                        // Success!
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }
 
            } else {
                println("    skipping: " + aDriver.getClass().getName());
            }
 
        }
 
        ....
    }

Driver

根据选择的driver,查看其connect源码,得知Driver只是简单解析驱动管理器的命令,生成不同策略的连接。

 @Override
    public java.sql.Connection connect(String url, Properties info) throws SQLException {

            ...
            ConnectionUrl conStr = ConnectionUrl.getConnectionUrlInstance(url, info);
            //根据不能的协议创建不同策略的Connection
            switch (conStr.getType()) {
                case SINGLE_CONNECTION:
                    return com.mysql.cj.jdbc.ConnectionImpl.getInstance(conStr.getMainHost());

                case LOADBALANCE_CONNECTION:
                    return LoadBalancedConnectionProxy.createProxyInstance((LoadbalanceConnectionUrl) conStr);

                case FAILOVER_CONNECTION:
                    return FailoverConnectionProxy.createProxyInstance(conStr);

                case REPLICATION_CONNECTION:
                    return ReplicationConnectionProxy.createProxyInstance((ReplicationConnectionUrl) conStr);

                default:
                    return null;
            }

        ...
    }

1. Single:普通的一个连接,提供我们常见的Statement、PreparedStatement一系列的数据操作.其配置如下

jdbc:mysql://ip:port/dbname

2. Loadbalace:底层代理多个Single连接.其配置如下

jdbc:mysql:loadbalance://[host1][:port],[host2][:port][,[host3][:port]]/dbname

通常在遇到通讯异常或者提交/回滚事务的时候才更换连接,它的核心目的有两个:

  1. 让调用者可以重复使用动态代理连接。
  2. 以事务为单位的负载均衡。

使用此模式,必须要将多台Mysql数据的一致性放在最首要的位置来考虑(不推荐)

3. Failover:底层代理多个Single连接.其配置如下

jdbc:mysql://[primary host][:port],[secondary host 1][:port]/dbname

底层的连接出状况时候,关闭旧连接,获取新连接,其主要有2种方式:

  1. 自动切换连接,对事务操作影响及大
  2. 失败让调用者感知,再调用则切换

使用此模式,必须要将多台Mysql数据的一致性放在最首要的位置来考虑(不推荐)

4. Replication:底层代理多个Single连接.其配置如下

jdbc:mysql:replication://[master host][:port],[slave host 1][:port],[slave host 2][:port]/dbname

底层会建立两组连接,一组负责读操作,一组负责写为主操作.通过设置Connection.setReadOnly(false),驱动将会保证你的请求会到主库。否则,读库。

Connection

不管Driver层选择了何种策略,最终干活的还是ConnectionImpl.

. 1.  ConnectionImpl通过解析各咱url后面的参数,具体参数含意请参考《Mysql配置文档

  2.  通过createNewIO,创建Socket与Mysql数据管理软件的数据交互

PS:8版本没有MysqlIO类,用NativeSession了

总结

不要小瞧Connector,他也能做许多事情。关于《Mysql配置文档》与源码相结合。会有更多发现。

比如引入第三方包p6spy,更换Driver,输出sql完整日志
jdbc:p6spy:mysql://ip:port/dbname

<dependency>
    <groupid>p6spy</groupid>
    <artifactid>p6spy</artifactid>
    <version>x.x.x</version>
</dependency>

 

主要参考

Mysql配置文档

Mysql Connector/J 源码分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值