項目上用的Spring JDBC,是通過ResultSetMetaData接口來調用具體數據庫的JDBC實現類來獲取數據庫返回結果集的。
在項目開發中,發現在MySQL中使用的別名沒有辦法被正常解析,意思就是說,給字段另外賦予的別名沒有生效,取的是字段原來的字段名。具體是比如給user_name取了個別名為user_name_old,最終返回的結果並不是別名user_name_old,而是原名user_name。
跟蹤代碼,發現在MySQL的JDBC實現中的ResultSetMetaData.getColumnName(int column)方法中存在一些特定的邏輯。
public String getColumnName(int column) throws SQLException { if (this.useOldAliasBehavior) { // false return this.getField(column).getName(); } else { String name = this.getField(column).getNameNoAliases(); // 取非別名 return name != null && name.length() == 0 ? this.getField(column).getName() : name; } }
因為this.useOldAliasBehavior屬性為false,因此最終走的是else的邏輯,也就走的是Field.getNameNoAliases()方法。
public String getNameNoAliases() throws SQLException { if (this.useOldNameMetadata) { // false return this.getName(); } else { return this.connection != null && this.connection.versionMeetsMinimum(4, 1, 0) ? this.getOriginalName() : this.getName(); } }
因此我們最終把問題定位到this.useOldAliasBehavior屬性上,這個屬性是可以通過JDBC驅動地址配置的。
useOldAliasMetadataBehavior=true
完整的驅動地址應該是這樣的:
jdbc:mysql://localhost/testDB?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true
添加上該屬性,就會發現問題得到了解決。
"我不能悲傷地坐在你身旁。"