一般获取数据库连接的程序

Class.forName("com.mysql.jdbc.Driver");
final Connection connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/testDB","guoxiaoming","guoxiaoming");

-----------------------------

注册mysql驱动类下次再说,目前重点介绍Connection的建立

-----------------------------

public interface Connection  extends Wrapper {

JDK的Connection提供了一种标准,与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。

该Connection接口被数据库驱动类实现,保存有数据库连接中的IO类。

JDBC当中的DriverManager类封装了获取Connection对象的统一方法

public static Connection getConnection(String url, String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties(); // Gets the classloader of the code that called this method, may
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader(); if (user != null) {
info.put("user", user);
}
if (password != null) {
info.put("password", password);
} return (getConnection(url, info, callerCL));
}

进入getConnection(url,info,callerCL)方法查看可以看到,

Connection result = di.driver.connect(url, info);

代码最终获取了Connection对象

对应的driver驱动类实现,在jdbc当中

public class NonRegisteringReplicationDriver extends NonRegisteringDriver {
public NonRegisteringReplicationDriver() throws SQLException {
super();
} /*
* (non-Javadoc)
*
* @see java.sql.Driver#connect(java.lang.String, java.util.Properties)
*/
public Connection connect(String url, Properties info) throws SQLException {
return connectReplicationConnection(url, info);
}
}

看到connectReplicationConnection(url,info)方法在父类NonRegisteringDriver类当中

return new ReplicationConnection(masterProps, slavesProps);

看到该类

public ReplicationConnection(Properties masterProperties,
Properties slaveProperties) throws SQLException {
this.driver = new NonRegisteringDriver();
this.slaveProperties = slaveProperties;
this.masterProperties = masterProperties; this.initializeMasterConnection();
this.initializeSlaveConnection(); this.currentConnection = this.masterConnection;
}

初始化了两个链接,一个是masterConnection 一个是slaveConnection

看注释

/**
* Connection that opens two connections, one two a replication master, and
* another to one or more slaves, and decides to use master when the connection
* is not read-only, and use slave(s) when the connection is read-only.
*
* @version $Id: ReplicationConnection.java,v 1.1.2.1 2005/05/13 18:58:38
* mmatthews Exp $
*/

我们最终看到在ConnectionImpl类当中

protected static Connection getInstance(String hostToConnectTo,
int portToConnectTo, Properties info, String databaseToConnectTo,
String url) throws SQLException {
if (!Util.isJdbc4()) {
return new ConnectionImpl(hostToConnectTo, portToConnectTo, info,
databaseToConnectTo, url);
} return (Connection) Util.handleNewInstance(JDBC_4_CONNECTION_CTOR,
new Object[] {
hostToConnectTo, Integer.valueOf(portToConnectTo), info,
databaseToConnectTo, url }, null);
}

  实例化了该类的一个子类

public class JDBC4Connection extends ConnectionImpl

 通过构造方法

public JDBC4Connection(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException {
super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url);
// TODO Auto-generated constructor stub
}

在其父类中

protected ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info,
String databaseToConnectTo, String url)
throws SQLException { this.connectionCreationTimeMillis = System.currentTimeMillis(); if (databaseToConnectTo == null) {
databaseToConnectTo = "";
}

重点关于方法

public void createNewIO(boolean isForReconnect)
throws SQLException {
synchronized (getConnectionMutex()) {
// Synchronization Not needed for *new* connections, but defintely for
// connections going through fail-over, since we might get the
// new connection up and running *enough* to start sending
// cached or still-open server-side prepared statements over
// to the backend before we get a chance to re-prepare them... Properties mergedProps = exposeAsProperties(this.props); if (!getHighAvailability()) {
connectOneTryOnly(isForReconnect, mergedProps); return;
} connectWithRetries(isForReconnect, mergedProps);
}
}

最终我们看到在coreConnect方法中实现了具体的链接

private void coreConnect(Properties mergedProps) throws SQLException,
IOException {
int newPort = 3306;
String newHost = "localhost"; String protocol = mergedProps.getProperty(NonRegisteringDriver.PROTOCOL_PROPERTY_KEY); if (protocol != null) {
// "new" style URL if ("tcp".equalsIgnoreCase(protocol)) {
newHost = normalizeHost(mergedProps.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY));
newPort = parsePortNumber(mergedProps.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY, "3306"));
} else if ("pipe".equalsIgnoreCase(protocol)) {
setSocketFactoryClassName(NamedPipeSocketFactory.class.getName()); String path = mergedProps.getProperty(NonRegisteringDriver.PATH_PROPERTY_KEY); if (path != null) {
mergedProps.setProperty(NamedPipeSocketFactory.NAMED_PIPE_PROP_NAME, path);
}
} else {
// normalize for all unknown protocols
newHost = normalizeHost(mergedProps.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY));
newPort = parsePortNumber(mergedProps.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY, "3306"));
}
} else { String[] parsedHostPortPair = NonRegisteringDriver
.parseHostPortPair(this.hostPortPair);
newHost = parsedHostPortPair[NonRegisteringDriver.HOST_NAME_INDEX]; newHost = normalizeHost(newHost); if (parsedHostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] != null) {
newPort = parsePortNumber(parsedHostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX]);
}
} this.port = newPort;
this.host = newHost; this.io = new MysqlIO(newHost, newPort,
mergedProps, getSocketFactoryClassName(),
getProxy(), getSocketTimeout(),
this.largeRowSizeThreshold.getValueAsInt());
this.io.doHandshake(this.user, this.password,
this.database);
}

在new MysqlIO类当中的构造方法中实现

 public MysqlIO(String host, int port, Properties props,
String socketFactoryClassName, MySQLConnection conn,
int socketTimeout, int useBufferRowSizeThreshold) throws IOException, SQLException {
this.connection = conn; if (this.connection.getEnablePacketDebug()) {
this.packetDebugRingBuffer = new LinkedList<StringBuffer>();
}
this.traceProtocol = this.connection.getTraceProtocol(); this.useAutoSlowLog = this.connection.getAutoSlowLog(); this.useBufferRowSizeThreshold = useBufferRowSizeThreshold;
this.useDirectRowUnpack = this.connection.getUseDirectRowUnpack(); this.logSlowQueries = this.connection.getLogSlowQueries(); this.reusablePacket = new Buffer(INITIAL_PACKET_SIZE);
this.sendPacket = new Buffer(INITIAL_PACKET_SIZE); this.port = port;
this.host = host; this.socketFactoryClassName = socketFactoryClassName;
this.socketFactory = createSocketFactory();
this.exceptionInterceptor = this.connection.getExceptionInterceptor(); try {
this.mysqlConnection = this.socketFactory.connect(this.host,
this.port, props); if (socketTimeout != 0) {
try {
this.mysqlConnection.setSoTimeout(socketTimeout);
} catch (Exception ex) {
/* Ignore if the platform does not support it */
}
} this.mysqlConnection = this.socketFactory.beforeHandshake(); if (this.connection.getUseReadAheadInput()) {
this.mysqlInput = new ReadAheadInputStream(this.mysqlConnection.getInputStream(), 16384,
this.connection.getTraceProtocol(),
this.connection.getLog());
} else if (this.connection.useUnbufferedInput()) {
this.mysqlInput = this.mysqlConnection.getInputStream();
} else {
this.mysqlInput = new BufferedInputStream(this.mysqlConnection.getInputStream(),
16384);
} this.mysqlOutput = new BufferedOutputStream(this.mysqlConnection.getOutputStream(),
16384); this.isInteractiveClient = this.connection.getInteractiveClient();
this.profileSql = this.connection.getProfileSql();
this.autoGenerateTestcaseScript = this.connection.getAutoGenerateTestcaseScript(); this.needToGrabQueryFromPacket = (this.profileSql ||
this.logSlowQueries ||
this.autoGenerateTestcaseScript); if (this.connection.getUseNanosForElapsedTime()
&& Util.nanoTimeAvailable()) {
this.useNanosForElapsedTime = true; this.queryTimingUnits = Messages.getString("Nanoseconds");
} else {
this.queryTimingUnits = Messages.getString("Milliseconds");
} if (this.connection.getLogSlowQueries()) {
calculateSlowQueryThreshold();
}
} catch (IOException ioEx) {
throw SQLError.createCommunicationsException(this.connection, 0, 0, ioEx, getExceptionInterceptor());
}
}
this.mysqlConnection = this.socketFactory.connect(this.host,this.port, props);
这样就返回了Socket对象 在StandardSocketFactory类当中
if (this.host != null) {
if (!(wantsLocalBind || wantsTimeout || needsConfigurationBeforeConnect)) {
InetAddress[] possibleAddresses = InetAddress
.getAllByName(this.host); Throwable caughtWhileConnecting = null; // Need to loop through all possible addresses, in case
// someone has IPV6 configured (SuSE, for example...) for (int i = 0; i < possibleAddresses.length; i++) {
try {
this.rawSocket = new Socket(possibleAddresses[i],
port); configureSocket(this.rawSocket, props); break;
} catch (Exception ex) {
caughtWhileConnecting = ex;
}
} if (rawSocket == null) {
unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting);
}
} else {
// must explicitly state this due to classloader issues
// when running on older JVMs :(
try { InetAddress[] possibleAddresses = InetAddress
.getAllByName(this.host); Throwable caughtWhileConnecting = null; Object localSockAddr = null; Class<?> inetSocketAddressClass = null; Constructor<?> addrConstructor = null; try {
inetSocketAddressClass = Class
.forName("java.net.InetSocketAddress"); addrConstructor = inetSocketAddressClass
.getConstructor(new Class[] {
InetAddress.class, Integer.TYPE }); if (wantsLocalBind) {
localSockAddr = addrConstructor
.newInstance(new Object[] {
InetAddress
.getByName(localSocketHostname),
new Integer(0 /*
* use ephemeral
* port
*/) }); }
} catch (Throwable ex) {
unwrapExceptionToProperClassAndThrowIt(ex);
} // Need to loop through all possible addresses, in case
// someone has IPV6 configured (SuSE, for example...) for (int i = 0; i < possibleAddresses.length; i++) { try {
this.rawSocket = new Socket(); configureSocket(this.rawSocket, props); Object sockAddr = addrConstructor
.newInstance(new Object[] {
possibleAddresses[i],
Integer.valueOf(port) });
// bind to the local port if not using the ephemeral port
if (localSockAddr != null) {
socketBindMethod.invoke(rawSocket,
new Object[] { localSockAddr });
} connectWithTimeoutMethod.invoke(rawSocket,
new Object[] { sockAddr,
Integer.valueOf(connectTimeout) }); break;
} catch (Exception ex) {
this.rawSocket = null; caughtWhileConnecting = ex;
}
} if (this.rawSocket == null) {
unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting);
} } catch (Throwable t) {
unwrapExceptionToProperClassAndThrowIt(t);
}
} return this.rawSocket;
}

针对host可能对应多个ip的可能性,连接到其中一个ip之后就break退出

MySQL驱动阅读------Connection连接的建立,基于JDBC-----5.1.26的更多相关文章

  1. java web应用连接mysql会突然connection连接失败

    tomcat6.0 mysql5.1 项目:java web项目 问题:原本项目运行了好几天了,一直没发现问题,突然今天报数据库连接异常,进入看日志发现 ### Error querying data ...

  2. Windows环境下 PyQt5 如何安装MySql驱动 (PyQt5连接MYSQL时显示Driver not loaded解决方案)

    参考文章: https://blog.csdn.net/qq_38198744/article/details/80261695 前文说过如何在Ubuntu环境下 为PyQt5  安装MySql驱动, ...

  3. MySQL驱动阅读------executeQuery查询的过程,基于JDBC-----5.1.26

    Statement statement = connection.createStatement(); final ResultSet resultSet = statement.executeQue ...

  4. Spring Boot连接MySQL长时间不连接后报错`com.mysql.cj.core.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.`的解决办法

    报错:com.mysql.cj.core.exceptions.ConnectionIsClosedException: No operations allowed after connection ...

  5. Eclipse中利用JSP把mysql-connector-java-8.0.13.jar放到WebContent\WEB-INF\lib中连接MySQL数据库时Connection conn = DriverManager.getConnection(url,username,password)报错的解决办法

    开发环境: 1.系统:windows 7/8/10均可 2.jdk:1.8.0_144 3.服务器:apache-tomcat-9.0.8 4.IDE:eclipse+jsp 0.网页代码如下: &l ...

  6. windows10 下使用Pycharm2016 基于Anaconda3 Python3.6 安装Mysql驱动总结

    本文记录:在PyCharm2016.3.3 中基于Anaconda3 Python3.6版本安装Python for Mysql驱动.尝试了安装Mysql-Connector成功,但是连接数据库时驱动 ...

  7. Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决

    Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决 I. 概述 1.1 JDBC概念 JDBC(Java Database Connectivity ...

  8. SQL Server 2012实施与管理实战指南(笔记)——Ch6连接的建立和问题排查

    6.连接的建立和问题排查 会话的建立分成2个部分: 1.连接,即找到这个实例 2.认证,告诉sql server谁要连接 目录 6.连接的建立和问题排查 6.1协议选择和别名 6.1.1 服务器网络配 ...

  9. Go-MySQL-Driver:一个Go语言的轻量级极速的mysql驱动

    Go语言的 database/sql 包的一个 MySQL驱动. 特性 轻量级与快速 原生Go语言,没有C绑定,只有纯Go 没有不安全的操作(类型转换等) 动态处理崩溃的连接 动态连接池 支持大于16 ...

随机推荐

  1. SharePoint PerformancePoint Service-PowerShell

    1. 配置托管服务账户 Set-SPPerformancePointSecureDataValues -ServiceApplication "PerformancePoint Servic ...

  2. Find发帖水王哥

    Find发帖水王 传说贴吧有一大“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子.坊间风闻该“水王”发帖数目超过了帖子总数的一半.如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的 ...

  3. Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记

    第一章 Thread导论 为何要用Thread ? 非堵塞I/O      I/O多路技术      轮询(polling)      信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...

  4. Android开发_控制硬加速hardwareAccelerated

    控制硬加速 hardwareAccelerated也是一种优化的手段 从Android3.0 (API level11)开始,Android的2D显示管道被被设计得更加支持硬加速了.硬加速使用GPU承 ...

  5. 也谈android开发图像压缩

    long long ago,给学院做的一个通讯录App需要有一个上传图像的功能,冥思苦想,绞尽脑汁后来还是没解决(学生时代的事),于是就直接上传原图了,一张图片2M到3M,这样我的应用发布之后,那绝对 ...

  6. linux中的网络通信指令 分类: 学习笔记 linux ubuntu 2015-07-06 16:02 134人阅读 评论(0) 收藏

    1.write write命令通信是一对一的通信,即两个人之间的通信,如上图. 效果图 用法:write <用户名> 2.wall wall指令可将信息发送给每位同意接收公众信息的终端机用 ...

  7. ubuntu首次给root用户设置密码

    用过ubuntu的人都知道,刚安装好root用户是没有密码的,没有密码我们就没法用root用户登录 给root用户设置密码输入命令sudo passwd,然后系统会让你输入密码,这时输入的密码就是ro ...

  8. flexbox 兼容安卓4.3

                 border:1px solid red;              overflow: hidden;                           font-siz ...

  9. JS实例(二)

    一:注册页面 包括非空验证.邮箱验证.密码相等验证,在输入之前提示文字,获得焦点时文字清除颜色变化,输入正确显示正确图片,错误显示错误图片,所有验证通过才可提交,重置会重置回初始模样. 效果图如下: ...

  10. jquery刷新iframe页面的方法

    1,reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当 ...