本文来自网易云社区
作者:孙波
最近在使用Mybatis的过程中,无意中踩到了一个坑,导致生成的sql语句不能在DDB上正确的执行并抛出异常:
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
int rows = ps.getUpdateCount();
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
}
Statement是专门用于执行SQL语句的接口,这里的实例则用的是最基本的
DelegatingPreparedStatement,在ps对象中,基本数据类型存储在
new String(((ByteArrayInputStream)((java.io.InputStream[])((JDBC4PreparedStatement)((DelegatingPreparedStatement)((DelegatingPreparedStatement)ps)._stmt)._stmt).parameterStreams)[9]).buf)
public boolean execute() throws SQLException {
checkOpen();
if (getConnectionInternal() != null) {
getConnectionInternal().setLastUsed();
}
try {
return ((PreparedStatement) getDelegate()).execute();
} catch (SQLException e) {
handleException(e);
return false;
}
}
for (int i = 0; i < batchedParameterStrings.length; i++) {
checkAllParametersSet(batchedParameterStrings[i], batchedParameterStreams[i], i);
sendPacket.writeBytesNoNull(this.staticSqlStrings[i]);
if (batchedIsStream[i]) {
streamToBytes(sendPacket, batchedParameterStreams[i], true, batchedStreamLengths[i], useStreamLengths);
} else {
sendPacket.writeBytesNoNull(batchedParameterStrings[i]);
}
}
if (hexEscape) {
packet.writeStringNoNull("x");
} else if (this.connection.getIO().versionMeetsMinimum(4, 1, 0)) {
packet.writeStringNoNull("_binary");
}
public void setNonNullParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType)
throws SQLException {
ByteArrayInputStream bis = new ByteArrayInputStream(parameter);
ps.setBinaryStream(i, bis, parameter.length);
}
<table tableName="A_Table" domainObjectName="table">
<property name="useActualColumnNames" value="true"/>
<columnOverride column="B_column" javaType="String" jdbcType="BLOB"/>
</table>
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return rs.getString(columnName);
}
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.getEncoding();
stringVal = this.thisRow.getString(internalColumnIndex, encoding, this.connection);
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Blob blob = rs.getBlob(columnName);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
return geneValue(returnValue);
}
private String geneValue(byte[] returnValue) {
try {
if (returnValue != null) {
//把byte转化成string
return new String(returnValue, DEFAULT_CHARSET);
} else {
return null;
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
<table tableName="A_Table" domainObjectName="table">
<property name="useActualColumnNames" value="true"/>
<columnOverride column="B_column" javaType="String" jdbcType="BLOB"
typeHandler="customTypeHandler"/>
</table>