MyBatis批量更新异常:列不能为空

时间:2015-08-26 03:34:57

标签: mysql sql mybatis

Blow是我的桌子

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> 

以下是我的更新数据:

user1{ id:1, username:"test1", priority:1 } 
user2{ id:1, priority:3 } 

当我使用batchUpdate一起更新user1和user2时,我得到以下异常:

  

org.springframework.dao.DataIntegrityViolationException:###错误   更新数据库。原因:   com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   专栏&#39;优先级&#39;不能为空###错误可能涉及   defaultParameterMap ###设置参数时发生错误###   SQL:SET username = CASE WHEN id =?然后 ? END,priority = CASE WHEN   ID =?然后 ?什么时候id =?然后 ? END,WHERE id IN(?,?)###原因:   com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   列&#39;用户名&#39;不能为空; SQL [];专栏&#39; cspuid&#39;不可能是   空值;嵌套异常是   com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   专栏&#39; cspuid&#39;不能为空   org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:85)at   组织工作室。   org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)at   org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)at at   org.mybatis.spring.SqlSessionTemplate $ SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365)at at   $ Proxy8.update(未知来源)at   org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:251)at at   org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:82)at at   org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)at   $ Proxy69.batchUpdateByKey(未知来源)

当SQL Logger打印下面的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更改为自动,它也不会抛出异常。似乎更新colummns在更新数据List中应该相同。

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> 

1 个答案:

答案 0 :(得分:1)

试试这个:

<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>