Mysql MyBatis批量更新异常:列不能为null
这是我的桌子Mysql MyBatis批量更新异常:列不能为null,mysql,sql,mybatis,Mysql,Sql,Mybatis,这是我的桌子 CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` VARCHAR}(255) NOT NULL, `priority` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 下面是我的SQL文
CREATE TABLE `user`
( `id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` VARCHAR}(255) NOT NULL,
`priority` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
下面是我的SQL文件
<update id="batchUpdate">
UPDATE user <trim prefix="SET" suffixOverrides=",">
<trim prefix="username=CASE" suffix="END,">
<foreach collection="list" item="item" index="index" separator=" ">
<if test="item.username!=null">WHEN id=#{item.id,jdbcType=BIGINT} THEN #{item.username,jdbcType=VARCHAR}</if>
</foreach>
</trim>
<trim prefix="priority=CASE" suffix="END,">
<foreach collection="list" item="item" index="index" separator=" ">
<if test="item.priority!=null">WHEN id=#{item.id,jdbcType=BIGINT} THEN #{item.priority,jdbcType=BIGINT}</if>
</foreach>
</trim>
</trim>
WHERE id IN
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">#{item.id,jdbcType=BIGINT}
</foreach>
</update>
当我使用batchUpdate同时更新user1和user2时,出现了以下异常:
org.springframework.dao.DataIntegrityViolationException:####错误
正在更新数据库。原因:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
“优先级”列不能为null####错误可能涉及
defaultParameterMap###设置参数时出错###
SQL:当id=时设置用户名=大小写?那么?结束,优先级=发生时的情况
id=?那么?当id=?那么?结束,其中id在(?)###原因中:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
“用户名”列不能为空;SQL[];列“cspuid”不能为空
无效的嵌套异常是
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
列“cspuid”在上不能为空
org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:85)位于
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)位于
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)位于
org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIffailable(MyBatisExceptionTranslator.java:71)位于
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365)位于
$Proxy8。更新(未知源)位于
org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:251)位于
org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:82)位于
org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)位于
$Proxy69.batchUpdateByKey(未知源)
当SQL记录器打印以下SQL时,可以在mysql:SQL中成功执行:
UPDATE user SET username=CASE WHEN id=2 THEN 'test1' END, priority=CASE WHEN id=2 THEN 3 WHEN id=1 THEN 1 END WHERE id IN ( 2 , 1 )
当我分别更新user1和user2时,它会成功地更新它们。若我将user1和user2更改为blow,它也不会抛出异常。似乎更新数据列表中的更新列应该是相同的
user1{ id:1, priority:1 } user2{ id:1, priority:3 }
这个问题非常奇怪,因为SQL打印可以在mysql中成功执行。是关于MyBatis的问题吗
另一个批量更新方法如下。它很简单,但总是返回1/0,不返回受影响的行。有什么好方法可以让行数受到影响吗
<update id="batchUpdate">
<foreach collection="list" item="item" index="index" separator=";">
UPDATE user <trim prefix="SET" suffixOverrides=",">
<if test="item.username!=null">username=#{item.username,jdbcType=VARCHAR}</if>
<if test="item.priority!=null">priority=#{item.priority,jdbcType=BIGINT}</if>
WHERE id=#{item.id,jdbcType=BIGINT}
</foreach>
</update>
更新用户
用户名=#{item.username,jdbcType=VARCHAR}
优先级=#{item.priority,jdbcType=BIGINT}
其中id=#{item.id,jdbcType=BIGINT}
试试这个:
<update id="batchUpdate">
UPDATE user
SET
username = CASE
<foreach collection="list" item="item" index="index" separator=" ">
<if test="item.username!=null">
WHEN id = #{item.id,jdbcType=BIGINT} THEN #{item.username,jdbcType=VARCHAR}
</if>
</foreach>
ELSE username
END
,
priority = CASE
<foreach collection="list" item="item" index="index" separator=" ">
<if test="item.priority!=null">
WHEN id = #{item.id,jdbcType=BIGINT} THEN #{item.priority,jdbcType=BIGINT}
</if>
</foreach>
ELSE priority
END
WHERE id IN
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>
更新用户
设置
用户名=大小写
当id={item.id,jdbcType=BIGINT}时,则{item.username,jdbcType=VARCHAR}
ELSE用户名
结束
,
优先权=案例
当id={item.id,jdbcType=BIGINT}时,则{item.priority,jdbcType=BIGINT}
其他优先事项
结束
我在哪里
#{item.id,jdbcType=BIGINT}
我不能编辑这个,因为没有断线,很乱。我刚刚格式化了它,它工作了!非常感谢。我很好奇为什么需要其他。如果没有ELSE
mybatis从mapper文件生成的sql实际上可以在mysql中执行。日志程序打印的SQL:更新用户集username=CASE(当id=2时)然后“test1”结束,优先级=CASE(当id=2时)然后是3
。我想知道为什么。(有点晚了,但我想澄清一下)在这个例子中,ELSE
语句是不必要的。如果没有“WHERE-id IN…”
Guys,这是必要的,在某些情况下,如果没有else语句,可能会像:“UPDATE user SET username=CASE END,priority=CASE END WHERE-id IN(1,2,3)”,这取决于mysql配置,可能会导致无效的查询失败,因为它不知道更新什么。为了在我的示例中使用语法正确的更新查询,我将当前参数作为else状态返回。如果字段值相同,MySQL本身不会更改任何内容,这没关系。
<update id="batchUpdate">
UPDATE user
SET
username = CASE
<foreach collection="list" item="item" index="index" separator=" ">
<if test="item.username!=null">
WHEN id = #{item.id,jdbcType=BIGINT} THEN #{item.username,jdbcType=VARCHAR}
</if>
</foreach>
ELSE username
END
,
priority = CASE
<foreach collection="list" item="item" index="index" separator=" ">
<if test="item.priority!=null">
WHEN id = #{item.id,jdbcType=BIGINT} THEN #{item.priority,jdbcType=BIGINT}
</if>
</foreach>
ELSE priority
END
WHERE id IN
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>