mysql和Mapper中批量更新数据写法

本文介绍如何使用MyBatis进行批量更新和插入操作,通过Mapper文件中的foreach标签实现动态SQL,提高处理大量数据时的效率。示例展示了如何更新订单状态及批量插入分词记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • mapper写法:
<update id="updateOrderStateByOrderId" parameterType="java.util.List">
   update t_replace_order set
   Forder_state =
   <foreach collection="list" item="item" index="index" separator=" " open="case Forder_id" close="end">
      when #{item.orderId,jdbcType=BIGINT} then #{item.orderState,jdbcType=INTEGER}
   </foreach>
   ,Forder_state_desc =
   <foreach collection="list" item="item" index="index" separator=" " open="case Forder_id" close="end">
      when #{item.orderId,jdbcType=BIGINT} then #{item.orderStateDesc,jdbcType=VARCHAR}
   </foreach>
   ,Fmodify_time=
   <foreach collection="list" item="item" index="index" separator=" " open="case Forder_id" close="end">
      when #{item.orderId,jdbcType=BIGINT} then #{item.modifyTime,jdbcType=TIMESTAMP}
   </foreach>
   where Forder_id in
   <foreach collection="list" index="index" item="item" separator="," open="(" close=")">
      #{item.orderId,jdbcType=BIGINT}
   </foreach>
</update>

    //这句sql的意思是,更新Forder_state字段,如果Forder_id=#{item.orderId,jdbcType=BIGINT} 则Forder_state的值为 

    //#{item.orderState,jdbcType=INTEGER}更多Forder_id和需要更新的字段就以此类推 

  • dao接口
//Map中key对应mysql中取值字段,Map中value对应取值字段的值,把map看做一个bean更加好理解
Integer updateOrderStateByOrderId(@Param("list")List<Bean> list);
  • 逻辑调用

     List<Bean> list = //Bean集合
     //批量更新
     Integer num =  updateOrderStateByOrderId(list);
  • 对应mysql中写法:
UPDATE ticket_db.t_replace_order 
SET Forder_state =
CASE
    Forder_id 
    WHEN '1' THEN
    0 
    WHEN '2' THEN
    2 
    WHEN '3' THEN
    1 
END 
WHERE
    Forder_id IN ( '1', '2', '3' ) 

 

    //这句sql的意思是,更新Forder_state字段,如果Forder_id=1 则Forder_state的值为0,
    //如果Forder_id=2 则dingdan的值为2,如果Forder_id=3 则Forder_state的值为1,更多Forder_id就以此类推

批量插入

 int insertMore(List<Fenci> record);


<insert id="insertMore" parameterType="java.util.List">
    insert into t_fenci ( Fword, Ftype,
    Fto_id, Flocation, Fnum,
    Fword_type,Fstart_offset, Fend_offset,
    Fcreate_time, Fmodify_time)
    values
    <foreach collection ="list" item="reddemCode" index= "index" separator =",">
      (
      #{reddemCode.word}, #{reddemCode.type},
      #{reddemCode.toId},
      #{reddemCode.location},
      #{reddemCode.num}, #{reddemCode.wordType},#{reddemCode.startOffset},#{reddemCode.endOffset},
      #{reddemCode.createTime},#{reddemCode.modifyTime}
      )
    </foreach >
  </insert>

 

<think>我们正在处理一个关于在MyBatis中使用XML配置实现MySQL批量更新的问题。 根据引用[1],我们知道在MySQL JDBC URL中设置`rewriteBatchedStatements=true``allowMultiQueries=true`参数有助于批量操作。 引用[2][3]展示了OracleMySQL中不同的批量更新写法。特别注意,MySQL不支持像Oracle那样的PL/SQL块(begin...end;),所以我们需要调整写法。 在MyBatis中,MySQL批量更新通常有两种方式: 1. 使用`<foreach>`标签拼接多个更新语句,并通过分号分隔,然后配合JDBC参数`allowMultiQueries=true`来允许一次执行多条SQL。 2. 使用`case when`语句构建一个更新多个记录的单个SQL语句。 但是,请注意,引用[3]中展示了一个嵌套foreach的批量更新,但这种方式在MySQL中需要开启多语句支持。 我们将展示两种方式: 方式一:使用foreach循环生成多个update语句(需要开启allowMultiQueries) 方式二:使用case when(适合单字段更新,多字段更新会复杂) 由于用户要求批量修改数据,我们假设需要根据不同的条件更新多个记录。 示例场景:根据id更新不同记录的nameemail字段。 方式一(推荐,且简单): 在MyBatis的mapper.xml中,我们可以这样写: ```xml <update id="batchUpdate" parameterType="java.util.List"> <foreach collection="list" item="item" index="index" separator=";"> UPDATE user_table SET name = #{item.name}, email = #{item.email} WHERE id = #{item.id} </foreach> </update> ``` 同时,确保JDBC URL中设置了`allowMultiQueries=true`,否则执行多条语句会报错。 方式二:使用case when(适用于更新多个字段,但SQL较长) ```xml <update id="batchUpdate" parameterType="java.util.List"> UPDATE user_table SET name = CASE id <foreach collection="list" item="item"> WHEN #{item.id} THEN #{item.name} </foreach> END, email = CASE id <foreach collection="list" item="item"> WHEN #{item.id} THEN #{item.email} </foreach> END WHERE id IN <foreach collection="list" item="item" open="(" separator="," close=")"> #{item.id} </foreach> </update> ``` 但是,方式二在更新多个字段时,每个字段都需要一个CASE语句,且当记录数很大时,SQL语句会很长。 注意:在方式二中,如果某个id在列表中出现多次,则最后一个出现的会生效(因为SQL中WHEN的顺序就是foreach的顺序)。另外,如果列表中有重复id,建议去重。 根据引用[1],我们还需要在JDBC URL中设置`rewriteBatchedStatements=true`来优化批量更新性能(对于方式一,开启这个参数可以将多个语句打包发送,提高效率)。但是,方式二是一个单独的SQL,不需要这个参数。 因此,推荐使用方式一,因为它简单直观,且通过开启多语句支持,可以一次执行多个更新。但是要注意SQL注入风险,确保传入的id等参数是安全的。 另外,引用[3]中提到一个嵌套foreach的批量更新,它更新了不同语言环境下的多个字段。我们可以参考其思路,但注意它也是使用分号分隔多个更新语句,所以同样需要开启多语句支持。 总结:在MySQL中,使用MyBatis进行批量更新,可以采用分号分隔多个update语句的方式,并设置JDBC参数`allowMultiQueries=true`。 注意:在配置文件中,我们使用`&`来转义`&`,所以URL中应该是`&allowMultiQueries=true`。 最后,我们给出一个完整的配置示例: 在application.properties(或类似配置文件)中: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true ``` 在mapper.xml中,使用方式一的写法。 但是,如果用户不想开启多语句支持(因为多语句可能带来安全风险),那么可以采用方式二,但要注意方式二的局限性(如SQL长度限制,以及更新逻辑的复杂性)。 因此,请根据实际需求选择。 相关问题: 1. 在MyBatis中,如何配置MySQL的JDBC URL以支持批量更新? 2. 除了使用多个update语句,还有哪些方法可以实现MyBatis批量更新MySQL数据? 3. 使用多个update语句进行批量更新时,需要注意哪些安全问题?</think>在Java中使用MyBatis的XML配置实现MySQL批量更新,主要有两种常用写法。以下是详细配置说明: ### 方法1:使用`<foreach>`拼接多个UPDATE语句(需开启多语句支持) ```xml <update id="batchUpdate" parameterType="java.util.List"> <foreach collection="list" item="item" separator=";"> UPDATE your_table SET column1 = #{item.value1}, column2 = #{item.value2} WHERE id = #{item.id} </foreach> </update> ``` **关键配置**: 1. JDBC URL需添加参数: ```ini jdbc:mysql://host:port/db?allowMultiQueries=true&rewriteBatchedStatements=true ``` - `allowMultiQueries=true`:允许分号分隔的多语句执行 - `rewriteBatchedStatements=true`:优化批量性能[^1] 2. Java调用: ```java List<YourEntity> dataList = ...; // 待更新数据集合 sqlSession.update("batchUpdate", dataList); ``` ### 方法2:使用CASE-WHEN动态生成单语句(无需多语句支持) ```xml <update id="batchUpdate" parameterType="java.util.List"> UPDATE your_table SET column1 = CASE id <foreach collection="list" item="item"> WHEN #{item.id} THEN #{item.value1} </foreach> END, column2 = CASE id <foreach collection="list" item="item"> WHEN #{item.id} THEN #{item.value2} </foreach> END WHERE id IN ( <foreach collection="list" item="item" separator=","> #{item.id} </foreach> ) </update> ``` ### 避坑指南 1. **SQL注入风险**: - 禁止在`${}`中拼接用户输入,必须使用`#{}`参数化[^3] - 示例错误写法:`WHERE id = ${item.id}` ❌ 2. **事务控制**: ```java try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) { YourMapper mapper = session.getMapper(YourMapper.class); for (YourEntity item : dataList) { mapper.updateItem(item); // 单条更新操作 } session.commit(); // 统一提交 } ``` 3. **性能优化**: - 单批次数据量建议500-1000条 - 超大批量时需分页处理 ### 配置验证 检查JDBC连接参数: ```java System.out.println(conn.getClientInfo()); // 输出rewriteBatchedStatements等实际生效值 ``` > 两种方法各有优劣:方法1代码简洁但需多语句权限;方法2兼容性更好但SQL较长。根据实际数据库权限选择即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值