You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为@MybatisPlusTest的嵌入式H2数据库配置大小写忽略?

解决@MybatisPlusTest中H2数据库列名大小写敏感问题

问题背景

使用Spring + MyBatis Plus进行单元测试时,通过@MybatisPlusTest注解自动创建的嵌入式H2数据库,执行自定义查询后返回的Map结果集中,列名默认是大写(如NAME),无法通过小写的name获取值。相关信息如下:

数据库启动日志

2023-06-08 10:36:02.187  INFO 1911 --- [           main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
2023-06-08 10:36:02.749  INFO 1911 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:e9cde56b-3395-44fb-8251-c79b0b36e653;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'

表结构(schema-h2.sql)

create table if not exists person
(
    id   int auto_increment primary key,
    name varchar(50) not null,
    age  int         not null
);

Mapper代码

@Repository
public interface PersonMapper extends BaseMapper<Person> {
    @Select("select name, age from person")
    public List<Map<String, Object>> selectCertainColumns();
}

可行解决方案

由于无法直接修改嵌入式H2的JDBC URL,可通过以下几种方式解决列名大小写问题:

1. 在SQL中指定小写列别名

修改Mapper的查询语句,用双引号包裹小写列名作为别名,强制H2返回小写的列名:

@Repository
public interface PersonMapper extends BaseMapper<Person> {
    @Select("select name as \"name\", age as \"age\" from person")
    public List<Map<String, Object>> selectCertainColumns();
}

这样查询结果的Map中就会以小写的name、age作为key。

2. 配置MyBatis自动转换列名为小写

在测试环境的配置文件(如src/test/resources/application.properties)中添加MyBatis Plus配置:

# 开启下划线转驼峰规则(兼容下划线格式列名)
mybatis-plus.configuration.map-underscore-to-camel-case=true
# 使用列标签而非原始列名
mybatis-plus.configuration.use-column-label=true
# 强制将结果列名转为小写
mybatis-plus.configuration.lower-case-column-names=true

添加后,MyBatis会自动将查询结果的列名转为小写,直接用rows.get(0).get("name")即可获取值。

3. 自定义BeanPostProcessor修改DataSource URL

通过Spring的BeanPostProcessor拦截自动创建的DataSource,在JDBC URL中添加CASE_INSENSITIVE_IDENTIFIERS=TRUE参数:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.lang.reflect.Field;

@Component
public class H2DataSourcePostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DataSource) {
            DataSource dataSource = (DataSource) bean;
            try {
                // 反射获取原始URL
                Field urlField = dataSource.getClass().getDeclaredField("url");
                urlField.setAccessible(true);
                String originalUrl = (String) urlField.get(dataSource);
                // 添加大小写不敏感参数
                String newUrl = originalUrl + ";CASE_INSENSITIVE_IDENTIFIERS=TRUE";
                // 重新构建DataSource
                return DataSourceBuilder.create()
                        .url(newUrl)
                        .username("sa")
                        .password("")
                        .driverClassName(dataSource.getClass().getName())
                        .build();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return bean;
    }
}

将这个类放在测试类同包下,Spring启动时会自动拦截并修改DataSource,实现H2列名大小写不敏感。

4. 使用ResultMap映射列名

在Mapper中定义ResultMap,明确指定列名与Map key的对应关系:

@Repository
public interface PersonMapper extends BaseMapper<Person> {
    @ResultMap("personMap")
    @Select("select name, age from person")
    public List<Map<String, Object>> selectCertainColumns();

    @ResultMap(id = "personMap", value = {
            @Result(column = "NAME", property = "name"),
            @Result(column = "AGE", property = "age")
    })
    void dummy(); // 仅用于定义ResultMap,无需实现
}

这样查询结果的Map会按照配置,将大写列名映射为小写key。

内容的提问来源于stack exchange,提问作者Hi computer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:53:16