设为首页 收藏本站
查看: 583|回复: 0

[经验分享] Mysql JDBC驱动源码分析(处理结果集)五

[复制链接]

尚未签到

发表于 2016-10-19 07:42:33 | 显示全部楼层 |阅读模式
  一,现在已经返回了结果集,接下来是对返回数据的分析
  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;
}
   
  
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-288114-1-1.html 上篇帖子: MySQL入门很简单-学习笔记 下篇帖子: mysql left join查询,比较两个表不同的行
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表