zoukankan      html  css  js  c++  java
  • 解决:oracle+myBatis ResultMap 类型为 map 时,表字段类型有 Long/Blob/Clob 时报错

    前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" 。如果数据库中的表里有字段类型为 Long 等类型时,mybatis 在执行 sql 时会报错,如果表中有 Blob、Clob 类型在转 json 是也会报错,而且我这里也需要将这几种类型都转为 String 类型到前端。

    long 类型 sql 报错:

    Blob/Clob 转 json 报错:

    解决方案:

    自定义 typeHandle 来统一处理数据库这些特殊的字段。

    这里 typeHandle 里面使用注解配置 JdbcType 和 JavaType。这两个注解的定义是:

    • @MappedTypes 定义的是 JavaType 类型,可以指定哪些 Java 类型被拦截。
    • @MappedJdbcTypes 定义的是 JdbcType 类型,它需要满足枚举类 org.apache.ibatis.type.JdbcType 所列的枚举类型。

    代码如下:

    myBatis 的配置文件中加入:

        <typeHandlers>
            <!--自定义处理 JdbcType.TIMESTAMP 和 java Object(Data)-->
            <typeHandler handler="com.yule.querydb.typehandler.MyObjectTimestampTypeHandle"/>
            <!--自定义处理 JdbcType.Clob 和 java Object(String)-->
            <typeHandler handler="com.yule.querydb.typehandler.MyObjectClobTypeHandle"/>
            <!--自定义处理 JdbcType.Blob 和 java Object(String)-->
            <typeHandler handler="com.yule.querydb.typehandler.MyObjectBlobTypeHandle"/>
            <!--自定义处理 JdbcType.LONGVARCHAR 和 java Object(String)-->
            <typeHandler handler="com.yule.querydb.typehandler.MyObjectLongTypeHandle"/>
        </typeHandlers>

    这些 typeHandle 类源码:

    package com.yule.querydb.typehandler;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.MappedJdbcTypes;
    import org.apache.ibatis.type.MappedTypes;
    
    import java.io.StringReader;
    import java.sql.*;
    
    /**
     * 自定义处理 JdbcType.Blob 和 java Object(String)
     * 处理转 json 报错,将 oracle.sql.Clob 类型转为 String 类型
     * copy org.apache.ibatis.type.ClobTypeHandler 类的处理
     * @author yule
     * @date 2018/10/9 17:57
     */
    @MappedTypes({Object.class})
    @MappedJdbcTypes(value = {JdbcType.CLOB})
    public class MyObjectClobTypeHandle extends BaseTypeHandler<Object> {
    
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
            String parameterStr = (String) parameter;
            StringReader reader = new StringReader(parameterStr);
            ps.setCharacterStream(i, reader, parameterStr.length());
        }
    
        @Override
        public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
            String value = "";
            Clob clob = rs.getClob(columnName);
            if(clob != null) {
                int size = (int)clob.length();
                value = clob.getSubString(1L, size);
            }
    
            return value;
        }
    
        @Override
        public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            String value = "";
            Clob clob = rs.getClob(columnIndex);
            if(clob != null) {
                int size = (int)clob.length();
                value = clob.getSubString(1L, size);
            }
    
            return value;
        }
    
        @Override
        public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            String value = "";
            Clob clob = cs.getClob(columnIndex);
            if(clob != null) {
                int size = (int)clob.length();
                value = clob.getSubString(1L, size);
            }
    
            return value;
        }
    
    }
    MyObjectBlobTypeHandle
    package com.yule.querydb.typehandler;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.MappedJdbcTypes;
    import org.apache.ibatis.type.MappedTypes;
    
    import java.io.StringReader;
    import java.sql.*;
    
    /**
     * 自定义处理 JdbcType.Blob 和 java Object(String)
     * 处理转 json 报错,将 oracle.sql.Blob 类型转为 String 类型
     * copy org.apache.ibatis.type.BlobTypeHandler 类的处理
     * @author yule
     * @date 2018/10/9 17:57
     */
    @MappedTypes({Object.class})
    @MappedJdbcTypes(value = {JdbcType.BLOB})
    public class MyObjectBlobTypeHandle extends BaseTypeHandler<Object> {
    
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
            byte[] parameterByteArray = (byte[]) parameter;
            String parameterStr = new String(parameterByteArray);
            StringReader reader = new StringReader(parameterStr);
            ps.setCharacterStream(i, reader, parameterStr.length());
        }
    
        @Override
        public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
            Blob blob = rs.getBlob(columnName);
            byte[] returnValue = null;
            if(null != blob) {
                returnValue = blob.getBytes(1L, (int)blob.length());
            }
    
            return returnValue == null ? "" : new String(returnValue);
        }
    
        @Override
        public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            Blob blob = rs.getBlob(columnIndex);
            byte[] returnValue = null;
            if(null != blob) {
                returnValue = blob.getBytes(1L, (int)blob.length());
            }
    
            return returnValue == null ? "" : new String(returnValue);
        }
    
        @Override
        public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            Blob blob = cs.getBlob(columnIndex);
            byte[] returnValue = null;
            if(null != blob) {
                returnValue = blob.getBytes(1L, (int)blob.length());
            }
    
            return returnValue == null ? "" : new String(returnValue);
        }
    }
    MyObjectLongTypeHandle
    package com.yule.querydb.typehandler;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.MappedJdbcTypes;
    import org.apache.ibatis.type.MappedTypes;
    
    import java.io.StringReader;
    import java.sql.*;
    
    /**
     * 自定义处理 JdbcType.LONGVARCHAR 和 java Object(String)
     * 处理转 mybatis 执行返回map的sql 报错,将 oracle Long 型转为 String 类型
     * @author yule
     * @date 2018/10/9 19:18
     */
    @MappedTypes({Object.class, String.class})
    @MappedJdbcTypes(value = {JdbcType.LONGVARCHAR})
    public class MyObjectLongTypeHandle extends BaseTypeHandler<Object> {
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
            String parameterStr = (String) parameter;
            StringReader reader = new StringReader(parameterStr);
            ps.setCharacterStream(i, reader, parameterStr.length());
        }
    
        @Override
        public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
            String str = rs.getString(columnName);
            return str != null ? str : "";
        }
    
        @Override
        public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            String str = rs.getString(columnIndex);
            return str != null ? str : "";
        }
    
        @Override
        public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            String str = cs.getString(columnIndex);
            return str != null ? str : "";
        }
    }


  • 相关阅读:
    SpringMVC+bootstrap-fileinput文件上传插件使用入门
    [Java]实现Comparable接口不严谨导致Comparison method violates its general contract!
    2021寒假ACM集训队第一次训练-搜索(一)
    第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛-热身赛
    2021蓝桥杯第三次训练赛
    2021年蓝桥杯第二次训练赛
    2021年蓝桥杯第一次训练赛
    HDU 1312 Red and Black
    HDU 1010 Tempter of the Bone
    HDU 3500 Fling
  • 原文地址:https://www.cnblogs.com/yuxiaole/p/9775389.html
Copyright © 2011-2022 走看看