Mysql JDBC驱动源码分析(处理结果集)五

一,现在已经返回了结果集,接下来是对返回数据的分析

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;
	}
 

猜你喜欢

转载自wuquanyin1011.iteye.com/blog/1415777
今日推荐