JDBC是怎么和数据库建立连接的

0o涛涛o0 发布于 2017/09/05 14:25
阅读 472
收藏 1

请问,JDBC是怎么和MySQL数据库建立连接的,我DEBUG追踪一直追踪到ConnectionImpl的构造方法。然后就没看懂是怎么连接连接

protected ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info,
			String databaseToConnectTo, String url)
			throws SQLException {
	
		this.connectionCreationTimeMillis = System.currentTimeMillis();
		this.pointOfOrigin = new Throwable();

      if (databaseToConnectTo == null) {
			databaseToConnectTo = "";
		}

		// Stash away for later, used to clone this connection for Statement.cancel
		// and Statement.setQueryTimeout().
		//
		
		this.origHostToConnectTo = hostToConnectTo;
		this.origPortToConnectTo = portToConnectTo;
		this.origDatabaseToConnectTo = databaseToConnectTo;

		try {
			Blob.class.getMethod("truncate", new Class[] {Long.TYPE});
			
			this.isRunningOnJDK13 = false;
		} catch (NoSuchMethodException nsme) {
			this.isRunningOnJDK13 = true;
		}
		
		this.sessionCalendar = new GregorianCalendar();
		this.utcCalendar = new GregorianCalendar();
		this.utcCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
		
		//
		// Normally, this code would be in initializeDriverProperties,
		// but we need to do this as early as possible, so we can start
		// logging to the 'correct' place as early as possible...this.log
		// points to 'NullLogger' for every connection at startup to avoid
		// NPEs and the overhead of checking for NULL at every logging call.
		//
		// We will reset this to the configured logger during properties
		// initialization.
		//
		this.log = LogFactory.getLogger(getLogger(), LOGGER_INSTANCE_NAME, getExceptionInterceptor());

		// We store this per-connection, due to static synchronization
		// issues in Java's built-in TimeZone class...
		this.defaultTimeZone = Util.getDefaultTimeZone();
		
		if ("GMT".equalsIgnoreCase(this.defaultTimeZone.getID())) {
			this.isClientTzUTC = true;
		} else {
			this.isClientTzUTC = false;
		}

		this.openStatements = new HashMap<Statement, Statement>();
		
		if (NonRegisteringDriver.isHostPropertiesList(hostToConnectTo)) {
			Properties hostSpecificProps = NonRegisteringDriver.expandHostKeyValues(hostToConnectTo);
			
			Enumeration<?> propertyNames = hostSpecificProps.propertyNames();
			
			while (propertyNames.hasMoreElements()) {
				String propertyName = propertyNames.nextElement().toString();
				String propertyValue = hostSpecificProps.getProperty(propertyName);
				
				info.setProperty(propertyName, propertyValue);
			}
		} else {
		
			if (hostToConnectTo == null) {
				this.host = "localhost";
				this.hostPortPair = this.host + ":" + portToConnectTo;
			} else {
				this.host = hostToConnectTo;
				
				if (hostToConnectTo.indexOf(":") == -1) {
					this.hostPortPair = this.host + ":" + portToConnectTo;
				} else {
					this.hostPortPair = this.host;
				}
			}
		}

		this.port = portToConnectTo;

		this.database = databaseToConnectTo;
		this.myURL = url;
		this.user = info.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY);
		this.password = info
				.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY);

		if ((this.user == null) || this.user.equals("")) {
			this.user = "";
		}

		if (this.password == null) {
			this.password = "";
		}

		this.props = info;
		
		
		
		initializeDriverProperties(info);
		
		
		try {
			this.dbmd = getMetaData(false, false);
			initializeSafeStatementInterceptors();
			createNewIO(false);
			unSafeStatementInterceptors();
		} catch (SQLException ex) {
			cleanup(ex);

			// don't clobber SQL exceptions
			throw ex;
		} catch (Exception ex) {
			cleanup(ex);

			StringBuffer mesg = new StringBuffer(128);

			if (!getParanoid()) {
				mesg.append("Cannot connect to MySQL server on ");
				mesg.append(this.host);
				mesg.append(":");
				mesg.append(this.port);
				mesg.append(".\n\n");
				mesg.append("Make sure that there is a MySQL server ");
				mesg.append("running on the machine/port you are trying ");
				mesg
						.append("to connect to and that the machine this software is "
								+ "running on ");
				mesg.append("is able to connect to this host/port "
						+ "(i.e. not firewalled). ");
				mesg
						.append("Also make sure that the server has not been started "
								+ "with the --skip-networking ");
				mesg.append("flag.\n\n");
			} else {
				mesg.append("Unable to connect to database.");
			}

			SQLException sqlEx = SQLError.createSQLException(mesg.toString(),
					SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE, getExceptionInterceptor());
			
			sqlEx.initCause(ex);
			
			throw sqlEx;
		}
		
		NonRegisteringDriver.trackConnection(this);
	}

也可能是我跟踪错了,也说不定,求大佬解释下,如果与数据库建立的连接,或者给本能详细解释jdbc源码的书籍也好啊

加载中
0
北极心
北极心

JDBC 是一个规范,遵循 JDBC 接口规范,各个数据库厂家各自实现自己的驱动程序(Driver)

这个驱动程序通过底层TCP通信,与数据库直接约定了数据交互协议,所以我们只需要用他的驱动就能管理他的数据库,你可以去看看mycat,或许会有些收获,大楷就是这样的

0
DeMoNHaDeS
DeMoNHaDeS

java mysql driver连接数据库其实就是跟mysql数据库建立一个连接,要学习的话还是建议自己看看这个构造方法里都做了什么。

---------

大体看了下,MysqlIO构造器中与数据库建立了一个socket连接,doHandshake方法验证一些信息握手

0
依然菜刀
依然菜刀

代码都在MysqlIO类中,自己去看看吧。。。。顺便说下,默认情况下mysql的驱动获取数据的resultset是憋内存的。。。。。即:一个sql查询返回1亿条数据,它会全部憋在内存里面,然后用数组给你去next。。。。好坑。。。。。。

依然菜刀
依然菜刀
回复 @0o涛涛o0 :非默认的话,可以使用游标,游标貌似可以使用3种方法,官方网站上有,一个是修改连接字符串,一个是通过API,一个是设置一个查询参数
0o涛涛o0
0o涛涛o0
非默认情况下呢
0
Jeremy_pan
Jeremy_pan

可以参考这里 https://github.com/seaswalker/mysql-driver/blob/master/note/connect.md

 

 

 

返回顶部
顶部