MySQL驱动阅读------Connection连接的建立,基于JDBC-----5.1.26
一般获取数据库连接的程序
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的更多相关文章
- java web应用连接mysql会突然connection连接失败
tomcat6.0 mysql5.1 项目:java web项目 问题:原本项目运行了好几天了,一直没发现问题,突然今天报数据库连接异常,进入看日志发现 ### Error querying data ...
- Windows环境下 PyQt5 如何安装MySql驱动 (PyQt5连接MYSQL时显示Driver not loaded解决方案)
参考文章: https://blog.csdn.net/qq_38198744/article/details/80261695 前文说过如何在Ubuntu环境下 为PyQt5 安装MySql驱动, ...
- MySQL驱动阅读------executeQuery查询的过程,基于JDBC-----5.1.26
Statement statement = connection.createStatement(); final ResultSet resultSet = statement.executeQue ...
- 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 ...
- 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 ...
- windows10 下使用Pycharm2016 基于Anaconda3 Python3.6 安装Mysql驱动总结
本文记录:在PyCharm2016.3.3 中基于Anaconda3 Python3.6版本安装Python for Mysql驱动.尝试了安装Mysql-Connector成功,但是连接数据库时驱动 ...
- Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决
Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决 I. 概述 1.1 JDBC概念 JDBC(Java Database Connectivity ...
- SQL Server 2012实施与管理实战指南(笔记)——Ch6连接的建立和问题排查
6.连接的建立和问题排查 会话的建立分成2个部分: 1.连接,即找到这个实例 2.认证,告诉sql server谁要连接 目录 6.连接的建立和问题排查 6.1协议选择和别名 6.1.1 服务器网络配 ...
- Go-MySQL-Driver:一个Go语言的轻量级极速的mysql驱动
Go语言的 database/sql 包的一个 MySQL驱动. 特性 轻量级与快速 原生Go语言,没有C绑定,只有纯Go 没有不安全的操作(类型转换等) 动态处理崩溃的连接 动态连接池 支持大于16 ...
随机推荐
- SharePoint PerformancePoint Service-PowerShell
1. 配置托管服务账户 Set-SPPerformancePointSecureDataValues -ServiceApplication "PerformancePoint Servic ...
- Find发帖水王哥
Find发帖水王 传说贴吧有一大“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子.坊间风闻该“水王”发帖数目超过了帖子总数的一半.如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的 ...
- Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记
第一章 Thread导论 为何要用Thread ? 非堵塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...
- Android开发_控制硬加速hardwareAccelerated
控制硬加速 hardwareAccelerated也是一种优化的手段 从Android3.0 (API level11)开始,Android的2D显示管道被被设计得更加支持硬加速了.硬加速使用GPU承 ...
- 也谈android开发图像压缩
long long ago,给学院做的一个通讯录App需要有一个上传图像的功能,冥思苦想,绞尽脑汁后来还是没解决(学生时代的事),于是就直接上传原图了,一张图片2M到3M,这样我的应用发布之后,那绝对 ...
- linux中的网络通信指令 分类: 学习笔记 linux ubuntu 2015-07-06 16:02 134人阅读 评论(0) 收藏
1.write write命令通信是一对一的通信,即两个人之间的通信,如上图. 效果图 用法:write <用户名> 2.wall wall指令可将信息发送给每位同意接收公众信息的终端机用 ...
- ubuntu首次给root用户设置密码
用过ubuntu的人都知道,刚安装好root用户是没有密码的,没有密码我们就没法用root用户登录 给root用户设置密码输入命令sudo passwd,然后系统会让你输入密码,这时输入的密码就是ro ...
- flexbox 兼容安卓4.3
border:1px solid red; overflow: hidden; font-siz ...
- JS实例(二)
一:注册页面 包括非空验证.邮箱验证.密码相等验证,在输入之前提示文字,获得焦点时文字清除颜色变化,输入正确显示正确图片,错误显示错误图片,所有验证通过才可提交,重置会重置回初始模样. 效果图如下: ...
- jquery刷新iframe页面的方法
1,reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当 ...