key,value,isDef关键字的隐藏bug
前言:
有个 老师傅创建表用关键字,返回的response用特殊字符导致的问题
1 ,表创建用到了关键字
表如下:
c
CREATE TABLE `system_xxx_config`(
`id` BIGINT NOT NULL COMMENT '主键' PRIMARY KEY,
`key` varchar(255) NOT NULL COMMENT '配置文件key',
`value` varchar(512) NOT NULL COMMENT '配置文件value',
...
) COMMENT 'xxx配置表' COLLATE = utf8mb4_unicode_ci;
正常我们写接口,使用BaseMapper集成 MyBatis实现简单的crud
代码如下
c
@Override
public R<GlobalConfigVo> queryxxxConfigVoByKey(String key) {
GlobalConfigVo configVo = new GlobalConfigVo();
GlobalConfigDO configDO = globalConfigMapper.selectOne(GlobalConfigDO::getKey,key);
if (Objects.isNull(configDO)){
return CommonResult.success(configVo);
}
BeanUtils.copyProperties(configDO, configVo);
return CommonResult.success(configVo);
}
但是就是报
SQL: SELECT id, key, value, deleted, create_time, update_time, creator, updater, x_channel, x_platform FROM system_global_config WHERE deleted = 0 AND (key = ?)
Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key, value, deleted, create_time, update_time, creator, xx,' at line 1
; bad SQL grammar []
2025-12-23 16:53:55.138 | ERROR 7 | http-nio-48091-exec-7 [TID: N/A] | [USER_ID: 1950821235660029954] [USER_IP: 42.99.63.70] [X_CHANNEL: zp] [X_PLATFORM: middleAndroid] [DEVICE_ID: 123321] [VERSION: 1.1.0.0.1] [REQUEST_ID: 2f9275a4-c754-4122xxxa902-93c241c54947] | c.h.f.w.c.h.
简单的说就是 使用key 、value 关键字,mybatis自动生成的sql用不了,会报错。
尝试
c
@Override
public R<GlobalxxConfigVo> queryGlobalxxxConfigVoByKey(String key) {
LambdaQueryWrapper<GlobalxxConfigDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(GlobalxxxConfigDO::getKey, key)
.eq(GlobalxxConfigDO::getDeleted, 0);
GlobalxxConfigDO configDO = globalxxConfigMapper.selectOne(wrapper);
GlobalxxConfigVo configVo = new GlobalxxxConfigVo();
BeanUtils.copyProperties(configDO, configVo);
return R.success(configVo);
}
还是报错误,
最终写
sql 做mapper映射解决bug
select xxx from xxx where xxx;
2、response返回值封装触发关键字 isDef
c
{
"code": 220,
"data": [
{
"config": "1024x",
"isDef": true
},
{
"config": "2048x",
"isDef": false
}
],
"msg": ""
}
正常封装对象:
c
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GlobalxxxConfigVo {
private String config;
private boolean isDef;
}
写好后返回是:
c
{
"code": 220,
"data": [
{
"config": "1024x",
"def": true
},
{
"config": "2048x",
"def": false
}
],
"msg": ""
}
查询原因是
问题分析:
在Java中,使用Lombok的@Data注解时,对于布尔类型的字段,Lombok生成的getter方法命名规则为:如果是基本类型boolean,字段名为isDef,则生成的getter方法为isDef(),setter方法为setDef(boolean)。但是,在序列化为JSON时,Jackson等序列化框架默认使用getter方法来确定字段名。对于布尔类型,可能会产生混淆。
字段名为isDef,Lombok生成的getter方法为isDef(),setter为setDef(boolean)。序列化框架可能会将字段名解析为def(因为getter方法名为isDef,去掉is后,首字母小写为def),所以返回的JSON中出现了def字段。
解决方案:
使用Jackson的@JsonProperty注解,指定序列化时的字段名。
c
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GlobalxxxConfigVo {
/**
* 视频彩铃分配率
*/
private String config;
/**
* 如果匹配默认的就是true 没有匹配到就是false
*/
@JsonProperty("isDef")
private boolean isDef;
}
都是师傅学到了。。。。
喜欢我的文章记得点个在看,或者点赞,持续更新中ing...