Oracle XMLType 欄位需特殊處理,MyBatis 預設不支援,需自定義 TypeHandler 實現 Java String 與 XMLType 雙向轉換。
public class XmltypeTypeHandler implements TypeHandler<String> {
@Override
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
if (StringUtils.isNotBlank(parameter)) {
// 獲取 Oracle 物理連接
DelegatingConnection conn = (DelegatingConnection) ps.getConnection().getMetaData().getConnection();
// 創建 XMLType 物件
XMLType xmltype = XMLType.createXML(conn.getDelegate(), parameter);
ps.setObject(i, xmltype);
} else {
ps.setString(i, null);
}
}
@Override
public String getResult(ResultSet rs, String columnName) throws SQLException {
// 查詢時使用 xmltype.getclobval() 返回 CLOB,直接當 String 讀取
return rs.getString(columnName);
}
@Override
public String getResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}
<typeHandlers>
<typeHandler javaType="java.lang.String"
jdbcType="UNDEFINED"
handler="com.yourpkg.XmltypeTypeHandler"/>
</typeHandlers>
因 JDBC 標準無 XMLType 枚舉,使用 UNDEFINED,實際映射時指定具體 Handler。
<insert id="insertContent">
INSERT INTO t_content (xml_file)
VALUES (#{xmlFile, javaType=string, jdbcType=UNDEFINED, typeHandler=com.yourpkg.XmltypeTypeHandler})
</insert>
<resultMap id="ContentResult" type="Content">
<result column="xml_file" property="xmlFile"
typeHandler="com.yourpkg.XmltypeTypeHandler"/>
</resultMap>
XMLType.createXML(connection, string) 創建 XMLType 物件。xmltype.getclobval() 轉為 CLOB,再以 String 讀取。避免使用 getstringval(),因其在字段為 NULL 時拋出 ORA-06502 錯誤。PreparedStatement 獲取物理連接(DelegatingConnection 解包)。public class XmltypeTypeHandler implements TypeHandler<String> {
@Override
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
if (StringUtils.isNotBlank(parameter)) {
DelegatingConnection conn = (DelegatingConnection) ps.getConnection().getMetaData().getConnection();
XMLType xmltype = XMLType.createXML(conn.getDelegate(), parameter);
ps.setObject(i, xmltype);
} else {
ps.setString(i, null);
}
}
// getResult 方法同上...
}
此模式同樣適用於 PostgreSQL jsonb、MySQL JSON 等特殊類型,只需替換具體的創建/讀取邏輯。