Oracle迁移到高斯查询字段默认小写的解决办法

 更新时间:2025年07月25日 09:23:54   作者:王ASC  
文章指出Oracle与高斯数据库查询结果字段大小写差异导致MyBatis Map接收兼容性问题,本文给大家介绍Oracle迁移到高斯查询字段默认小写的解决办法,感兴趣的朋友一起看看吧

一、问题说明

Oracle中,查询结果字段默认大写。

高斯中,查询结果字段默认小写。

在Mybatis的xml中,如果查询语句使用Map接收查询结果,使用resultType="java.util.HashMap"resultType="Map"等写法,返回的Map对象中,Key就是字段名,从Oracle迁移到高斯,大写变成小写,存在兼容性问题。

二、解决办法

方案1、使用字段别名

当代码中使用Map接收查询结果使用比较少时,可以直接修改sql,通过为字段指定别名的方式,实现最终字段名为大写,如上面演示的user_id AS "USER_ID"

方案2、自定义Mybatis拦截器

通过mybatis拦截器实现查询结果返回后,如果通过Map类型接收查询结果,将Key转为大写。

1. 创建自定义mybatis拦截器

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.lang.reflect.Method;
import java.util.*;
/**
 * @desc Map接收查询结果,将Map的Key转为大写,解决从Oracle切换高斯后,高斯默认小写,JSP字段绑定异常,生成推送文件字段变化等问题
 * {@link MapKeyUpperCase}
 */
@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {
                MappedStatement.class, Object.class, RowBounds.class,
                ResultHandler.class})})
public class MapKeyUpperCaseInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 执行原方法,获取返回结果
        Object result = invocation.proceed();
        // 获取当前执行的Mapper方法,Executor.query的第一个参数为MappedStatement
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        // 方法全路径:com.example.mapper.UserMapper.selectUserMap
        String methodName = mappedStatement.getId();
        // 通过反射获取Mapper接口的方法,检查是否有自定义注解
        String className = methodName.substring(0, methodName.lastIndexOf("."));
        String simpleMethodName = methodName.substring(methodName.lastIndexOf(".") + 1);
        Class<?> mapperInterface = Class.forName(className);
        Method method = Arrays.stream(mapperInterface.getMethods())
                .filter(m -> m.getName().equals(simpleMethodName))
                .findFirst().orElse(null);
        // 只对配置了自定义注解的方法生效
        if (method != null && method.isAnnotationPresent(MapKeyUpperCase.class)) {
            // 返回结果是List,处理每一项
            if (result instanceof List) {
                List<Map<?, ?>> resultList = (List<Map<?, ?>>) result;
                for (Map<?, ?> map : resultList) {
                    // 原记录索引替换为新记录
                    resultList.set(resultList.indexOf(map), upCaseResultMapKey(map));
                }
                return resultList;
            }
            // 返回单条记录
            else if (result instanceof Map) {
                return upCaseResultMapKey((Map<?, ?>) result);
            }
        }
        return result;
    }
    /**
     * @param resultMap 初始查询结果
     * @return java.util.HashMap<java.lang.Object, java.lang.Object>
     * @desc 将Map接收的查询结果的Key转为大写
     */
    private HashMap<Object, Object> upCaseResultMapKey(Map<?, ?> resultMap) {
        HashMap<Object, Object> newMap = new HashMap<>();
        for (Map.Entry<?, ?> entry : resultMap.entrySet()) {
            Object key = entry.getKey();
            Object value = entry.getValue();
            if (key instanceof String) {
                newMap.put(((String) key).toUpperCase(), value);
            } else {
                newMap.put(key, value);
            }
        }
        return newMap;
    }
    @Override
    public Object plugin(Object target) {
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        }
        return target;
    }
    @Override
    public void setProperties(Properties properties) {
    }
}

2. 创建自定义注解

import java.lang.annotation.*;
/**
 * @desc 声明在Mapper中以Map接收查询结果的查询方法上,标明该方法返回字段名称大写
 * {@link MapKeyUpperCaseInterceptor}
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MapKeyUpperCase {
}

3. 注册Mybatis拦截器

传统方式,在mybatis-config.xml中注册拦截器

<configuration>
    <plugins>
        <plugin interceptor="com.example.MapKeyUpperCaseInterceptor">
        </plugin>
    </plugins>
</configuration>

在Springboot中注册Mybatis拦截器,参考下面代码

@Configuration
public class MyBatisConfig {
    @Bean
    public MapKeyUpperCaseInterceptor mapKeyUpperCaseInterceptor() {
        return new MapKeyUpperCaseInterceptor();
    }
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource, MapKeyUpperCaseInterceptor mapKeyUpperCaseInterceptor) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setPlugins(mapKeyUpperCaseInterceptor); // 注册拦截器
        return factoryBean.getObject();
    }
}

4. 在需要将Map中的Key转为大写的方法上,声明自定义注解

在需要大写的mapper方法上声明该注解,实现返回Map对象Key是否大写的配置,如

@MapKeyUpperCase
Map<String, Object> getMap();
@MapKeyUpperCase
List<Map<String, Object>> getMapList();
@MapKeyUpperCase
Page<HashMap<String, String>> queryMapByPage(RowBounds rb);

到此这篇关于Oracle迁移到高斯,查询字段默认小写,解决办法的文章就介绍到这了,更多相关oracle查询字段默认小写内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Oracle设置时区和系统时间的多种实现方法

    Oracle设置时区和系统时间的多种实现方法

    在Oracle数据库中,设置时区和系统时间可以通过多种方法实现,本文通过代码示例给大家介绍了Oracle设置时区和系统时间的多种实现方法,需要的朋友可以参考下
    2024-02-02
  • 如何在Oracle数据库中更新CLOB字段

    如何在Oracle数据库中更新CLOB字段

    在Oracle数据库中,Blob和Clob分别是两种用来存储大数据的字段类型,下面这篇文章主要给大家介绍了关于如何在Oracle数据库中更新CLOB字段的相关资料,需要的朋友可以参考下
    2024-05-05
  • Oracle 错误代码整理总结

    Oracle 错误代码整理总结

    这篇文章主要介绍了Oracle 错误代码总结详细介绍的相关资料,需要的朋友可以参考下
    2016-09-09
  • Oracle 多行记录合并/连接/聚合字符串的几种方法

    Oracle 多行记录合并/连接/聚合字符串的几种方法

    怎么合并多行记录的字符串,一直是oracle新手喜欢问的SQL问题之一,关于这个问题的帖子我看过不下30个了,现在就对这个问题,进行一个总结。
    2009-11-11
  • Oracle 8i在P4上的安装

    Oracle 8i在P4上的安装

    Oracle 8i在P4上的安装...
    2007-03-03
  • oracle—SQL技巧之(二)WMSYS.WM_CONCAT函数实现多行记录用逗号拼接在一起

    oracle—SQL技巧之(二)WMSYS.WM_CONCAT函数实现多行记录用逗号拼接在一起

    由于业务系统的交易记录有很多,常常有些主管需要看到所有的记录情况;又不想滚动;接下来介绍使用Oracle自带的函数 WMSYS.WM_CONCAT,进行拼接,感兴趣的朋友可以了解下
    2013-01-01
  • Oracle通过procedure调用webservice接口的全过程

    Oracle通过procedure调用webservice接口的全过程

    存储过程是一组为了完成特定功能的sql语句集合,经过编译后存储在数据库中,用户通过制定存储过程的名字并给出参数(如果该过程带有参数)来执行他,本文介绍了Oracle通过procedure调用webservice接口的全过程,需要的朋友可以参考下
    2024-07-07
  • Oracle用户密码含特殊字符时登陆失败问题

    Oracle用户密码含特殊字符时登陆失败问题

    当Oracle数据库用户的密码含特殊字符如 @ 时,默认会将@后的字符解析为网络服务名而导致登陆失
    2014-07-07
  • Oracle数据库数据丢失恢复的几种方法总结

    Oracle数据库数据丢失恢复的几种方法总结

    相信大家无论是开发、测试还是运维过程中,都可能会因为误操作、连错数据库、用错用户、语句条件有误等原因,导致错误删除、错误更新等问题。当你捶胸顿足或吓得腿软时,肯定希望有办法来恢复这些数据。oracle就提供了一些强大的方法或机制,可以帮到有需要的你。
    2016-12-12
  • oracle中的substr()函数用法实例详解

    oracle中的substr()函数用法实例详解

    这篇文章主要给大家介绍了关于oracle中substr()函数用法的相关资料,substr函数是用于字符串的截取的函数,只适用于string类型,并不适用于字符数组,需要的朋友可以参考下
    2023-11-11

最新评论