一,现在已经返回了结果集,接下来是对返回数据的分析
ResultSet.next()只不过是对rowData集合的操作
public synchronized boolean next() throws SQLException {
checkClosed();
if (this.onInsertRow) {
this.onInsertRow = false;
}
if (this.doingUpdates) {
this.doingUpdates = false;
}
boolean b;
if (!reallyResult()) {
throw SQLError.createSQLException(
Messages
.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); //$NON-NLS-1$
}
if (this.thisRow != null) {
this.thisRow.closeOpenStreams();
}
if (this.rowData.size() == 0) {
b = false;
} else {
//下一行数据
this.thisRow = this.rowData.next();
if (this.thisRow == null) {
b = false;
} else {
clearWarnings();
b = true;
}
}
setRowPositionValidity();
return b;
}
以ResultSet.getByte("")获取数据为例
//findColumn()方法,会找到相应的索引位置
public byte[] getBytes(String columnName) throws SQLException {
return getBytes(findColumn(columnName));
}
public byte getByte(int columnIndex) throws SQLException {
if (!this.isBinaryEncoded) {
//先通getString获取
String stringVal = getString(columnIndex);
if (this.wasNullFlag || (stringVal == null)) {
return 0;
}
return getByteFromString(stringVal, columnIndex);
}
return getNativeByte(columnIndex);
}
//===========
//通过索引位置获取字符串值
public String getString(int columnIndex) throws SQLException {
String stringVal = getStringInternal(columnIndex, true);
if (this.padCharsWithSpace && stringVal != null) {
Field f = this.fields[columnIndex - 1];
if (f.getMysqlType() == MysqlDefs.FIELD_TYPE_STRING ) {
int fieldLength = (int)f.getLength() /* safe, bytes in a CHAR <= 1024 */ /
f.getMaxBytesPerCharacter(); /* safe, this will never be 0 */
int currentLength = stringVal.length();
if (currentLength < fieldLength) {
StringBuffer paddedBuf = new StringBuffer(fieldLength);
paddedBuf.append(stringVal);
int difference = fieldLength - currentLength;
paddedBuf.append(EMPTY_SPACE, 0, difference);
stringVal = paddedBuf.toString();
}
}
}
return stringVal;
}
//==================
protected String getStringInternal(int columnIndex, boolean checkDateTypes)
throws SQLException {
if (!this.isBinaryEncoded) {
checkRowPos();
checkColumnBounds(columnIndex);
if (this.fields == null) {
throw SQLError.createSQLException(
Messages
.getString("ResultSet.Query_generated_no_fields_for_ResultSet_99"), //$NON-NLS-1$
SQLError.SQL_STATE_INVALID_COLUMN_NUMBER, getExceptionInterceptor());
}
// JDBC is 1-based, Java is not !?
int internalColumnIndex = columnIndex - 1;
if (this.thisRow.isNull(internalColumnIndex)) {
this.wasNullFlag = true;
return null;
}
this.wasNullFlag = false;
//获取到相应的字段属性类
Field metadata = this.fields[internalColumnIndex];
String stringVal = null;
if (metadata.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
if (metadata.isSingleBit()) {
byte[] value = this.thisRow.getColumnValue(internalColumnIndex);
if (value.length == 0) {
return String.valueOf(convertToZeroWithEmptyCheck());
}
return String.valueOf(value[0]);
}
return String.valueOf(getNumericRepresentationOfSQLBitType(columnIndex));
}
String encoding = metadata.getCharacterSet();
//在根据next()操作时指定的thisRow中获取相应的数据(BufferRow)
stringVal = this.thisRow.getString(internalColumnIndex, encoding, this.connection);
//
// Special handling for YEAR type from mysql, some people
// want it as a DATE, others want to treat it as a SHORT
//
if (metadata.getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
if (!this.connection.getYearIsDateType()) {
return stringVal;
}
Date dt = getDateFromString(stringVal, columnIndex, null);
if (dt == null) {
this.wasNullFlag = true;
return null;
}
this.wasNullFlag = false;
return dt.toString();
}
// Handles timezone conversion and zero-date behavior
if (checkDateTypes && !this.connection.getNoDatetimeStringSync()) {
//所获取到的String值,根据metadata中的类型再进行相应的转换
switch (metadata.getSQLType()) {
case Types.TIME:
Time tm = getTimeFromString(stringVal, null, columnIndex,
this.getDefaultTimeZone(), false);
if (tm == null) {
this.wasNullFlag = true;
return null;
}
this.wasNullFlag = false;
return tm.toString();
case Types.DATE:
Date dt = getDateFromString(stringVal, columnIndex, null);
if (dt == null) {
this.wasNullFlag = true;
return null;
}
this.wasNullFlag = false;
return dt.toString();
case Types.TIMESTAMP:
Timestamp ts = getTimestampFromString(columnIndex,
null, stringVal, this.getDefaultTimeZone(), false);
if (ts == null) {
this.wasNullFlag = true;
return null;
}
this.wasNullFlag = false;
return ts.toString();
default:
break;
}
}
return stringVal;
}
return getNativeString(columnIndex);
}
//
//BufferRow继承了ResultSetRow下获取相应的值
public String getString(int columnIndex, String encoding, MySQLConnection conn)
throws SQLException {
if (this.isBinaryEncoded) {
if (isNull(columnIndex)) {
return null;
}
}
//指针指向到相应的列
findAndSeekToOffset(columnIndex);
long length = this.rowFromServer.readFieldLength();
if (length == Buffer.NULL_LENGTH) {
return null;
}
if (length == 0) {
return "";
}
// TODO: I don't like this, would like to push functionality back
// to the buffer class somehow
int offset = this.rowFromServer.getPosition();
//获取到值,后对string进行相应的转换
return getString(encoding, conn, this.rowFromServer.getByteBuffer(),
offset, (int) length);
}
//BufferRow
protected String getString(String encoding, MySQLConnection conn,
byte[] value, int offset, int length) throws SQLException {
String stringVal = null;
if ((conn != null) && conn.getUseUnicode()) {
try {
if (encoding == null) {
stringVal = StringUtils.toString(value);
} else {
SingleByteCharsetConverter converter = conn
.getCharsetConverter(encoding);
if (converter != null) {
//对编码的一些转换
stringVal = converter.toString(value, offset, length);
} else {
//或者常用类中的转换
stringVal = StringUtils.toString(value, offset, length, encoding);
}
}
} catch (java.io.UnsupportedEncodingException E) {
throw SQLError
.createSQLException(
Messages
.getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$
+ encoding + "'.", "0S100", this.exceptionInterceptor);
}
} else {
stringVal = StringUtils.toAsciiString(value, offset, length);
}
return stringVal;
}
分享到:
相关推荐
MySQL Connector/J是官方提供的JDBC驱动程序,它的源代码能帮助开发者深入理解数据库连接、数据传输以及SQL语句在Java中的执行过程。 首先,我们来看看JDBC的概念。JDBC是Java平台上的一个标准接口,由Sun ...
MySQL 8 数据库驱动源码分析 MySQL 是世界上最流行的开源关系型数据库管理系统之一,而 `mysql-connector-java` 是 MySQL 官方提供的用于 Java 应用程序连接到 MySQL 数据库的 JDBC 驱动程序。在 MySQL 8 版本中,...
MySQL的Java驱动程序,也称为JDBC驱动,实现了这些API,从而允许Java应用执行SQL语句、处理结果集以及进行事务管理等数据库操作。 首先,我们来看看Java连接MySQL的基本步骤: 1. 导入驱动:在Java代码中,你需要...
关于源码分析,MySQL JDBC驱动的源代码可以提供深入理解数据库连接的工作原理、事务处理、批处理以及错误处理机制等。对于开发者来说,阅读源码有助于优化性能,解决特定问题,或者为自定义功能提供灵感。 在工具...
在“mysql-driver:mysql jdbc驱动源码阅读”这个主题中,我们将深入探讨该驱动的工作原理、关键组件以及源码分析。 1. **JDBC驱动类型**: JDBC驱动分为四种类型:Type 1、Type 2、Type 3 和 Type 4。MySQL ...
- **处理结果集**:对于 SELECT 语句,可以获取 ResultSet 对象,遍历其中的数据;对于 INSERT、UPDATE 或 DELETE 语句,可以通过 getUpdateCount() 获取受影响的行数。 5. **学习资源** - **官方文档**:MySQL ...
压缩包中的“mysql-connector-java-5.1.18--源码”文件是MySQL的JDBC驱动源代码,通过阅读这些源代码,开发者可以深入了解JDBC驱动的工作原理,以及它是如何与MySQL服务器通信的。此外,这也有助于解决在使用过程中...
MySQL JDBC 5源码包含了用于连接、查询、事务处理、结果集处理等关键功能的类和方法。以下是一些主要的知识点: 1. **连接管理**:在`com.mysql.jdbc.Connection`类中,我们可以找到建立、管理和关闭数据库连接的...
源码分析可以帮助我们了解数据库连接、查询执行、结果集处理等过程的具体实现,这对于优化性能、解决兼容性问题或开发自定义驱动都是很有帮助的。 总之,这个资源对于学习和使用Java与MySQL数据库交互的开发者来说...
5. **处理结果**:对于查询操作,`executeQuery()`会返回一个`ResultSet`,我们可以遍历这个结果集获取数据。对于非查询操作,`executeUpdate()`将返回受影响的行数。 6. **关闭资源**:操作完成后,必须按照“后开...
通过JDBC,开发者可以执行SQL语句、处理结果集、事务管理等操作。 在Eclipse中,JDBC连接数据库的过程主要包括以下步骤: 1. **加载驱动**:使用`Class.forName()`方法加载数据库驱动,例如`Class.forName(...
6. **处理结果集**:遍历`ResultSet`,获取每条数据并进行处理。 7. **关闭资源**:最后记得关闭`ResultSet`、`Statement`和`Connection`,以释放数据库资源。 在给定的源码中,可能包含了一个封装好的分页查询...
关于源码分析,MySQL Connector/J的源码可以帮助我们深入理解JDBC驱动的工作原理,包括如何建立网络连接、解析SQL语句以及处理结果集等。源码中包含了如`com.mysql.jdbc.Driver`(驱动注册类)、`...
1. **DriverManager**: 这是Java数据库连接的入口点,负责管理所有的JDBC驱动。当Java应用通过`Class.forName()`加载了MySQL的驱动后,`DriverManager`会注册这个驱动,并根据用户提供的URL、用户名和密码建立到...
5. **处理结果集**:对于查询操作,可以通过ResultSet接口来处理返回的结果集。 6. **关闭资源**:确保所有打开的资源(如Connection、Statement、ResultSet等)都被正确关闭。 #### 二、如何与数据库建立连接 **...
博主可能分享了如何在项目中引入MySQL驱动库,以及处理连接、执行查询、处理结果集等方面的实践经验和技巧。 标签“源码”暗示了这篇博客可能包含了驱动的源代码分析,这对于理解数据库连接的工作原理、学习如何...
通过JDBC,你可以执行SQL语句,处理结果集,以及管理事务。在项目中,你会看到如何加载驱动,建立连接,执行SQL语句并获取结果。 5. **框架应用**:虽然题目没有明确指出使用了哪种框架,但常见的JavaWeb框架如...
标题中的“jdbc连接数据库:oracle/derby/mysql”是指使用Java Database Connectivity (JDBC) API来与三种不同的数据库...同时,了解并分析JDBC驱动源码有助于深入理解数据库操作的底层机制,提升开发和问题排查能力。
4. **demo**:演示示例代码,这些代码展示了如何使用MySQL Connector/J进行基本的数据库操作,如建立连接、执行SQL语句、处理结果集等。对于初学者来说,这是一个很好的起点,可以快速理解如何在实际项目中使用该...