问题场景:
IDEA使用EasyCode插件,生成mapper.xml中SQL执行时报错
- 在日常生产工作中,大家有时使用代码生成器生成基础代码,减轻搬砖负担。
- 本次问题为根据表生成基础
CURD代码
时,表字段名
与SQL关键字
冲突,导致报错,在此记录分享。 - 本文为大家整理了解决方案和配置方法(临时方案/永久方案),欢迎大家留言讨论,记得点赞收藏!
问题描述
- 在执行插入数据时,报错
java.sql.SQLSyntaxErrorException
:
- 放大图片看到提示,是在字段 [show] 附近出现解析错误:
- 再来看一下控制台打印的SQL:
- 可以看到字段 [show] 外并未使用
反引号
,因为其与MYSQL关键字或保留字
冲突,所以报错。再看一下自动生成mapper.xml
文件 中的SQL代码(此处代码省略了表名和冗余字段
):
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into table_name(name, parent_id, type, menu_url, status, show, icon,···)
values (#{name}, #{parentId}, #{type}, #{menuUrl}, #{status}, #{show}, #{icon},···)
</insert>
解决方案:
- 此时报错原因已经清楚,就是在 [show] 字段上加上
反引号
,如下(此处代码省略了表名和冗余字段
):
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into table_name(name, parent_id, type, menu_url, status, `show`, icon,···)
values (#{name}, #{parentId}, #{type}, #{menuUrl}, #{status}, #{show}, #{icon},···)
</insert>
-
问题解决!有帮助到你就
点个赞吧 ^.^
-
下面附上MYSQL关键字及保留字,供大家查询
—Tips:可以在下列网址中,使用Ctrl+F
在网页查找关键字:
链接: mysql5.7的关键字与保留字(mysql官网)
解决方案(一劳永逸版):
- 因为代码生成器未将表中字段名称加
反引号
,导致与MYSQL关键字或保留字
冲突的Bug经常会出现,为此每次报错后再去修改,总会徒增很多工作量,如果业务代码嵌套多层,也会增加排查的难度。 - 我们可以更改代码生成的模板,自定义规则,生成代码时,将所有字段都加上反引号,一劳永逸,下文为大家介绍
EasyCode
修改mapper.xml
文件模板的方法:
1、在 IDEA 打开Settings
--> Other Settings
--> EasyCode
--> Template
,在右侧找到 mapper.xml.vm
选中,然后修改模板内容:
2、在右侧模板中,读取表格字段的方法名外侧添加反引号,为方便大家使用,将模板整体放在下方,大家可以直接复制粘贴,全量替换:
##引入mybatis支持
$!{mybatisSupport.vm}
##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))
##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
#set($pk = $tableInfo.pkColumn.get(0))
#end
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="$!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao">
<resultMap type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}" id="$!{tableInfo.name}Map">
#foreach($column in $tableInfo.fullColumn)
<result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
#end
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="$!{tableInfo.name}Map">
select
#foreach($column in $tableInfo.otherColumn)`$!column.obj.name`#if($velocityHasNext), #end#end
from $!tableInfo.obj.name
where `$!pk.obj.name` = #{$!pk.name}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="$!{tableInfo.name}Map">
select
#foreach($column in $tableInfo.otherColumn)`$!column.obj.name`#if($velocityHasNext), #end#end
from $!tableInfo.obj.name
<where>
#foreach($column in $tableInfo.fullColumn)
<if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
and `$!column.obj.name` = #{$!column.name}
</if>
#end
</where>
limit #{pageable.offset}, #{pageable.pageSize}
</select>
<!--统计总行数-->
<select id="count" resultType="java.lang.Long">
select count(1)
from $!tableInfo.obj.name
<where>
#foreach($column in $tableInfo.fullColumn)
<if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
and `$!column.obj.name` = #{$!column.name}
</if>
#end
</where>
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true">
insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)`$!column.obj.name`#if($velocityHasNext), #end#end)
values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end)
</insert>
<insert id="insertBatch" keyProperty="$!pk.name" useGeneratedKeys="true">
insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)`$!column.obj.name`#if($velocityHasNext), #end#end)
values
<foreach collection="entities" item="entity" separator=",">
(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end)
</foreach>
</insert>
<insert id="insertOrUpdateBatch" keyProperty="$!pk.name" useGeneratedKeys="true">
insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)`$!column.obj.name`#if($velocityHasNext), #end#end)
values
<foreach collection="entities" item="entity" separator=",">
(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end)
</foreach>
on duplicate key update
#foreach($column in $tableInfo.otherColumn)`$!column.obj.name` = values($!column.obj.name)#if($velocityHasNext),
#end#end
</insert>
<!--通过主键修改数据-->
<update id="update">
update $!{tableInfo.obj.name}
<set>
#foreach($column in $tableInfo.otherColumn)
<if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
`$!column.obj.name` = #{$!column.name},
</if>
#end
</set>
where `$!pk.obj.name` = #{$!pk.name}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete from $!{tableInfo.obj.name} where `$!pk.obj.name` = #{$!pk.name}
</delete>
</mapper>
3、此时再生成的代码所有字段都加上了反引号,不会再出现与MYSQL关键字或保留字
冲突的问题。
再看一下修改模板后生成的mapper.xml
文件(此处代码省略了表名和冗余字段
):
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into table_name(`name`, `parent_id`, `type`, `menu_url`, `status`, `show`, `icon`,···)
values (#{name}, #{parentId}, #{type}, #{menuUrl}, #{status}, #{show}, #{icon},···)
</insert>
- 大功告成!
以上为所有内容,如果问题还没有得到解决,欢迎大家留言讨论交流,有帮助到你就 点个赞吧 ^.^