开发环境:
- springboot 2.4.3
- baomidou 3.4.0
- mybatis plus 3.4.0
- jdk8
问题描述:
1、mybatis 使用baomidou插件,插入数据,代码非常简单,所有配置都检查完好,但插入失败(实体类没有使用 @TableField注解)。
int affect = userDao.insert(entry);
2、报错日志,mysql表字段全是驼峰,实体类也是驼峰,但报了一个下划线的字段,列不存在,字段不存在的错误;
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'user_id' in 'field list'
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'user_id' in 'field list'
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:88)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
at com.sun.proxy.$Proxy109.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:271)
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:60)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
at com.sun.proxy.$Proxy112.insert(Unknown Source)
原因分析:
经网上搜索一轮,基本上确定是baomidou偷偷把驼峰转为下划线了,但奇怪的是,application.properties文件已经有如下配置,为什么不生效呢?
#################### Mybatis ####################
mybatis-plus.configuration.map-underscore-to-camel-case=false
检查了下数据源的配置代码,发现factory这种写法是没有读取到配置的
@Bean(name = "hikariSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("hikariDataSource") DataSource dataSource)
throws Exception {
// 使用了mybatis插件,就不能用注释掉的bean
// SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
// 可以设置多个路径
bean.setDataSource(dataSource);
bean.setPlugins(paginationInterceptor(), new SqlStatementInterceptor(sqlLogConfig),
new SqlExecuteTimeCountInterceptor(sqlLogConfig));
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return bean.getObject();
}
解决方案:
因为DB里明确所有字段都是驼峰,而且DB实体类因为某些原因不能使用@TableField注解,所以在生成factory的时候,手工配置一下。
@Bean(name = "hikariSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("hikariDataSource") DataSource dataSource)
throws Exception {
// 使用了mybatis插件,就不能用注释掉的bean
// SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
// 可以设置多个路径
bean.setDataSource(dataSource);
bean.setPlugins(paginationInterceptor(), new SqlStatementInterceptor(sqlLogConfig),
new SqlExecuteTimeCountInterceptor(sqlLogConfig));
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
SqlSessionFactory factory = bean.getObject();
assert factory != null;
factory.getConfiguration().setMapUnderscoreToCamelCase(false);
return factory;
}