Java专题十四:JDBC

Java专题十四:JDBC

目录

14.1.JDBC框架

14.2.JDBCAPI

java.sql.Driver

  • Connection connect(String url, java.util.Properties info)

java.sql.DriverManager

  • static Connection getConnection(String url, String user, String password)

java.sql.Connection

  • Statement createStatement()

  • PreparedStatement prepareStatement(String sql)

  • CallableStatement prepareCall(String sql)

java.sql.Statement

  • ResultSet executeQuery(String sql)

  • int executeUpdate(String sql)

  • boolean execute(String sql)

java.sql.PreparedStatement

  • ResultSet executeQuery()

  • int executeUpdate()

  • boolean execute()

  • void setInt(int parameterIndex, int x)

  • void setString(int parameterIndex, String x)

java.sql.ResultSet

  • boolean next()

  • String getString(int columnIndex)

  • String getString(int columnLabel)

例,从user表中查询name为张三的用户信息:

String url = "jdbc:mysql://localhost:3306/mail_manager?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true";String user = "root";String password = "root";Connection conn = null;try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url, username, password); PreparedStatement ps = conn.prepareStatement("select name, email from user where name=?"); ps.setString(1, "张三"); ResultSet rs = ps.executeQuery(); while(rs.next()){ String username = rs.getString("name"); String email = rs.getString("email"); System.out.println(username); System.out.println(email); }}catch (ClassNotFoundException ignored){}

14.3.JDBC Driver

com.mysql.jdbc.NonRegisteringDriver

// com.mysql.jdbc.NonRegisteringDriverpublic Connection connect(String url, Properties info) { // ... com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url); // ...}protected static Connection getInstance(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException { return (Connection)(!Util.isJdbc4() ? new ConnectionImpl(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url) : (Connection)Util.handleNewInstance(JDBC_4_CONNECTION_CTOR, new Object[]{hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url}, (ExceptionInterceptor)null));}

com.mysql.jdbc.ConnectionImpl

// com.mysql.jdbc.ConnectionImplpublic ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException { // ... this.createNewIO(false); // ...}public void createNewIO(boolean isForReconnect) throws SQLException { synchronized(this.getConnectionMutex()) { Properties mergedProps = this.exposeAsProperties(this.props); if (!this.getHighAvailability()) { this.connectOneTryOnly(isForReconnect, mergedProps); } else { this.connectWithRetries(isForReconnect, mergedProps); } }}private void connectOneTryOnly(boolean isForReconnect, Properties mergedProps) throws SQLException { // ... this.coreConnect(mergedProps); // ...}private void coreConnect(Properties mergedProps) throws SQLException, IOException { // ... this.io = new MysqlIO(newHost, newPort, mergedProps, this.getSocketFactoryClassName(), this.getProxy(), this.getSocketTimeout(), this.largeRowSizeThreshold.getValueAsInt()); this.io.doHandshake(this.user, this.password, this.database); // ...}

com.mysql.jdbc.MysqlIO
通过Socket与MysqlServer通信,通过mysqlInput与mysqlOutput传输数据

// com.mysql.jdbc.MysqlIOpublic MysqlIO(String host, int port, Properties props, String socketFactoryClassName, MySQLConnection conn, int socketTimeout, int useBufferRowSizeThreshold) throws IOException, SQLException { // ... this.mysqlConnection = this.socketFactory.connect(this.host, this.port, props); 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); // ...}

com.mysql.jdbc.PreparedStatement
通过发送和接受Packet完成数据库查询

// com.mysql.jdbc.PreparedStatementpublic ResultSet executeQuery() throws SQLException { synchronized(this.checkClosed().getConnectionMutex()) { // ... Buffer sendPacket = this.fillSendPacket(); // ... this.results = this.executeInternal(this.maxRows, sendPacket, this.createStreamingResultSet(), true, metadataFromCache, false); // ... return this.results; }}protected ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, boolean queryIsSelectOnly, Field[] metadataFromCache, boolean isBatch) throws SQLException { synchronized(this.checkClosed().getConnectionMutex()) { // ... ResultSetInternalMethods rs; rs = locallyScopedConnection.execSQL(this, (String)null, maxRowsToRetrieve, sendPacket, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, this.currentCatalog, metadataFromCache, isBatch); // ... }}

com.mysql.jdbc.ConnectionImpl

// com.mysql.jdbc.ConnectionImplpublic ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata, boolean isBatch) throws SQLException { synchronized(this.getConnectionMutex()) { // ... ResultSetInternalMethods var36 = this.io.sqlQueryDirect(callingStatement, (String)null, (String)null, packet, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); // ... }}

com.mysql.jdbc.MysqlIO
通过Socket与MysqlServer通信,通过mysqlInput与mysqlOutput传输数据

// com.mysql.jdbc.MysqlIOfinal ResultSetInternalMethods sqlQueryDirect(StatementImpl callingStatement, String query, String characterEncoding, Buffer queryPacket, int maxRows, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata) throws Exception { // ... this.sendPacket.writeByte((byte)3); if (characterEncoding != null) { if (this.platformDbCharsetMatches) { this.sendPacket.writeStringNoNull(query, characterEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), this.connection); } else if (StringUtils.startsWithIgnoreCaseAndWs(query, "LOAD DATA")) { this.sendPacket.writeBytesNoNull(StringUtils.getBytes(query)); } else { this.sendPacket.writeStringNoNull(query, characterEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), this.connection); } } else { this.sendPacket.writeStringNoNull(query); } Buffer resultPacket = this.sendCommand(3, (String)null, queryPacket, false, (String)null, 0); // ...}final Buffer sendCommand(int command, String extraData, Buffer queryPacket, boolean skipCheck, String extraDataCharEncoding, int timeoutMillis) throws SQLException { // ... this.send(this.sendPacket, this.sendPacket.getPosition()); // ...}private final void send(Buffer packet, int packetLen) throws SQLException { // ... Buffer packetToSend = packet; packet.setPosition(0); packet.writeLongInt(packetLen - 4); packet.writeByte(this.packetSequence); // ... this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen); this.mysqlOutput.flush(); // ... }

14.4.Mysql Server

参考https://dev.mysql.com/doc/internals/en/mysql-server.html#mysqld_stmt_fetch

相关文章