3. Driver 源码

java.sql.Driver接口规定了Driver应该具有以下功能,重要的有三个acceptsURL判断jdbcUrl是否支持、创建一个连接、获取属性信息,三个主要接口。

下边以 NonRegisteringDriver​ 类的源码简单分析以下。

acceptsURL

acceptsURL(String url) 方法用来测试对指定的url,该驱动能否打开这个url连接。driver对自己能够连接的url会制定自己的协议,只有符合自己的协议形式的url才认为自己能够打开这个url,如果能够打开,返回true,反之,返回false;

Mysql-JDBC支持的驱动协议有:

  • jdbc:mysql+srv:
  • jdbc:mysql+srv:loadbalance:
  • jdbc:mysql+srv:replication:
  • mysqlx+srv:
  • jdbc:mysql:
  • jdbc:mysql:loadbalance:
  • jdbc:mysql:replication:
  • mysqlx:
connect

这里会根据URL 创建一个连接。一般是ConnectionImpl类型,下一篇文章会细说一下。其他类型的连接就先不看了。

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

    try {
        // 如果url是不自持的连接协议,则返回null
        if (!ConnectionUrl.acceptsUrl(url)) {
            return null;
        }

        ConnectionUrl conStr = ConnectionUrl.getConnectionUrlInstance(url, info);
        switch (conStr.getType()) {
            case SINGLE_CONNECTION:
                return com.mysql.cj.jdbc.ConnectionImpl.getInstance(conStr.getMainHost());

            case FAILOVER_CONNECTION:
            case FAILOVER_DNS_SRV_CONNECTION:
                return FailoverConnectionProxy.createProxyInstance(conStr);

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

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

            default:
                return null;
        }

    } catch (UnsupportedConnectionStringException e) {
        // when Connector/J can't handle this connection string the Driver must return null
        return null;

    } catch (CJException ex) {
        throw ExceptionFactory.createException(UnableToConnectException.class,
                Messages.getString("NonRegisteringDriver.17", new Object[] { ex.toString() }), ex);
    }
}

SINGLE_CONNECTION 会创建一个 ConnectionImpl

    public static JdbcConnection getInstance(HostInfo hostInfo) throws SQLException {
        return new ConnectionImpl(hostInfo);
    }
getPropertyInfo

获取这些属性信息 HOST、PORT、DBNAME、USER、PASSWORD

@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
    String host = "";
    String port = "";
    String database = "";
    String user = "";
    String password = "";

    if (!isNullOrEmpty(url)) {
        ConnectionUrl connStr = ConnectionUrl.getConnectionUrlInstance(url, info);
        if (connStr.getType() == Type.SINGLE_CONNECTION) {
            HostInfo hostInfo = connStr.getMainHost();
            info = hostInfo.exposeAsProperties();
        }
    }

    if (info != null) {
        host = info.getProperty(PropertyKey.HOST.getKeyName());
        port = info.getProperty(PropertyKey.PORT.getKeyName());
        database = info.getProperty(PropertyKey.DBNAME.getKeyName());
        user = info.getProperty(PropertyKey.USER.getKeyName());
        password = info.getProperty(PropertyKey.PASSWORD.getKeyName());
    }

    DriverPropertyInfo hostProp = new DriverPropertyInfo(PropertyKey.HOST.getKeyName(), host);
    hostProp.required = true;
    hostProp.description = Messages.getString("NonRegisteringDriver.3");

    DriverPropertyInfo portProp = new DriverPropertyInfo(PropertyKey.PORT.getKeyName(), port);
    portProp.required = false;
    portProp.description = Messages.getString("NonRegisteringDriver.7");

    DriverPropertyInfo dbProp = new DriverPropertyInfo(PropertyKey.DBNAME.getKeyName(), database);
    dbProp.required = false;
    dbProp.description = Messages.getString("NonRegisteringDriver.10");

    DriverPropertyInfo userProp = new DriverPropertyInfo(PropertyKey.USER.getKeyName(), user);
    userProp.required = true;
    userProp.description = Messages.getString("NonRegisteringDriver.13");

    DriverPropertyInfo passwordProp = new DriverPropertyInfo(PropertyKey.PASSWORD.getKeyName(), password);
    passwordProp.required = true;
    passwordProp.description = Messages.getString("NonRegisteringDriver.16");

    JdbcPropertySet propSet = new JdbcPropertySetImpl();
    propSet.initializeProperties(info);
    List<DriverPropertyInfo> driverPropInfo = propSet.exposeAsDriverPropertyInfo();

    DriverPropertyInfo[] dpi = new DriverPropertyInfo[5 + driverPropInfo.size()];
    dpi[0] = hostProp;
    dpi[1] = portProp;
    dpi[2] = dbProp;
    dpi[3] = userProp;
    dpi[4] = passwordProp;
    System.arraycopy(driverPropInfo.toArray(new DriverPropertyInfo[0]), 0, dpi, 5, driverPropInfo.size());

    return dpi;
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当你在 Java 应用程序中使用 `Class.forName` 方法尝试加载名为 `com.chenji60.cj.jdbc.Driver` 的类时,如果抛出 `ClassNotFoundException`,通常表示Java虚拟机(JVM)无法找到指定的类。这可能有以下几个原因: 1. **类路径(Classpath)问题**:`Class.forName` 需要在类路径(classpath)中能找到该类文件。如果你没有将包含 `Driver` 类的 JAR 文件添加到类路径,或者 JAR 文件中的类路径配置不正确,就会导致找不到类。 2. **包名拼写错误**:检查类名和包名是否完全匹配 `ClassNotFoundException` 中给出的全限定名。有时候由于拼写错误,即使类存在也可能无法找到。 3. **类未编译或不存在**:确认对应的源代码已经被编译并且生成了字节码,如果没有或者编译后的 `.class` 文件缺失,也会导致找不到类。 4. **类已被删除**:如果这个类文件因为某种原因从磁盘上被删除或者从项目的构建过程中移除了,`Class.forName` 就会找不到。 5. **权限问题**:如果你的应用程序没有足够的权限去访问特定的类,也可能会引发这个异常。 要解决这个问题,你可以尝试以下步骤: - 确保包含 `Driver` 类的 JAR 文件在类路径(classpath)中。 - 检查类名、包名以及全限定名的拼写。 - 如果是源码,确认已经编译并生成 `.class` 文件。 - 检查是否有权限问题,确保应用程序有访问所需的类文件的权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值