实用指南: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);
posted @ 2025-07-25 15:54  yfceshi  阅读(47)  评论(0)    收藏  举报