文章转载,原网址 https://www.jianshu.com/p/041bec8ae6d3
批量插入
xxxMapper部分代码
int insertList(List<WaterEle> list);
WaterEleMapper.xml部分代码
<!--批量增加测试-->
<insert id="insertList" parameterType="java.util.List">
insert into t_enterprise_water_ele
(
/*方法一*/
-- WATER_ELE_ID,
-- ENTERPRISE_ID,
-- ENTERPRISE_USCC,
-- ENTERPRISE_NAME,
-- YEARMONTH,
-- WATER_SIZE,
-- WATER_AMOUNT,
-- ELE_SIZE,
-- ELE_AMOUNT,
-- STATUS,
-- OPERATOR,
-- OPERATE_TIME
/*方法二*/
<include refid="Base_Column_List"/> ) VALUES <foreach collection="list" item="item" index="index" separator=","> ( #{item.waterEleId,jdbcType=VARCHAR}, #{item.enterpriseId,jdbcType=VARCHAR}, #{item.enterpriseUscc,jdbcType=VARCHAR}, #{item.enterpriseName,jdbcType=VARCHAR}, #{item.yearmonth,jdbcType=VARCHAR}, #{item.waterSize,jdbcType=DECIMAL}, #{item.waterAmount,jdbcType=VARCHAR}, #{item.eleSize,jdbcType=DOUBLE}, #{item.eleAmount,jdbcType=VARCHAR}, #{item.status,jdbcType=INTEGER}, #{item.operator,jdbcType=VARCHAR}, #{item.operateTime,jdbcType=TIMESTAMP} ) </foreach> </insert>
对于foreach标签的解释参考了网上的资料,具体如下:
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置
open表示该语句以什么开始
separator表示在每次进行迭代之间以什么符号作为分隔 符
close表示以什么结束
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:
1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map
使用批量插入执行的SQL语句应该等价于:
insert into redeem_code (batch_id, code, type, facevalue,create_user,create_time)
values (?,?,?,?,?,? ),(?,?,?,?,?,? ),(?,?,?,?,?,? ),(?,?,?,?,?,? )
批量更新
mybatis 实现批量更新
1、传list集合
单个字段
批量更新测试
<update id="updateByBatch" parameterType="java.util.List">
update t_goods
set NODE_ID=
<foreach collection="list" item="item" index="index" separator=" " open="case" close="end"> when GOODS_ID=#{item.goodsId} then #{item.nodeId} </foreach> where GOODS_ID in <foreach collection="list" index="index" item="item" separator="," open="(" close=")"> #{item.goodsId,jdbcType=BIGINT} </foreach> </update>
单个字段方法二
<update id="updateByBatch" parameterType="java.util.List">
UPDATE
t_goods
SET NODE_ID = CASE
<foreach collection="list" item="item" index="index"> WHEN GOODS_ID = #{item.goodsId} THEN #{item.nodeId} </foreach> END WHERE GOODS_ID IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item.goodsId} </foreach> </update>
以上单字段更新实际执行:UPDATE t_goods SET NODE_ID = CASE WHEN GOODS_ID = ? THEN ? END WHERE GOODS_ID IN ( ? )
多个字段
<update id="updateBatch" parameterType="java.util.List"> update t_user <trim prefix="set" suffixOverrides=","> <trim prefix="STATUS =case" suffix="end,"> <foreach collection="list" item="i" index="index"> <if test="i.status!=null"> when USER_ID=#{i.userId} then #{i.status} </if> </foreach> </trim> <trim prefix=" OPERATE_TIME =case" suffix="end,"> <foreach collection="list" item="i" index="index"> <if test="i.operateTime!=null"> when USER_ID=#{i.userId} then #{i.operateTime} </if> </foreach> </trim> <trim prefix="OPERATOR =case" suffix="end," > <foreach collection="list" item="i" index="index"> <if test="i.operator!=null"> when USER_ID=#{i.userId} then #{i.operator} </if> </foreach> </trim> </trim> where <foreach collection="list" separator="or" item="i" index="index" > USER_ID=#{i.userId} </foreach> </update>
int updateBatch(List<WaterEle> list);
更新多条记录的同一个字段为同一个值
<update id="updateByBatchPrimaryKey" parameterType="java.util.Map">
UPDATE t_goods
SET NODE_ID = #{nodeId}
WHERE GOODS_ID IN (${goodsIdList})
</update>
UPDATE t_goods SET NODE_ID = ? WHERE GOODS_ID IN (1,2,5);
2、传map/ 传String(同批量删除的"传map/ 传String")
<update id="deleteByPrimaryKey" parameterType="java.util.Map">
UPDATE t_order_checkout
SET NODE_ID = #{nodeId, jdbcType=VARCHAR}, OPERATOR = #{operator, jdbcType=VARCHAR}
WHERE CHECKOUT_ID IN (${checkoutIdList})
</update>
批量删除(数组)
1、传数组
int deleteByBatch(String[] array);
<delete id="deleteByBatch" parameterType="java.lang.String"> delete from t_enterprise_output_value where OUTPUT_ID IN <foreach collection="array" item="outputId" open="(" separator="," close=")"> #{outputId} </foreach> </delete>
2、传map / 传String
<delete id="deleteByRole" parameterType="java.util.Map">
DELETE
FROM
t_user_role
<where>
<if test="userIdList != null"> USER_ID IN (#{userIdList,jdbcType=VARCHAR}) </if> <if test="roleId != null"> AND ROLE_ID=#{roleId,jdbcType=VARCHAR} </if> <if test="sysCode != null"> AND SYSCODE=#{sysCode} </if> </where> </delete>
因为表中没有fileIds字段,所以如果传map进入的话,需要在map中定义该字段
map.put("fileIds","1,2,3");
//美元符$直接注入
<delete id="deleteByPrimaryKey" parameterType="java.util.Map">
DELETE FROM t_attachment WHERE FILE_ID IN (${fileIds})
</delete>
完整的sql语句是:DELETE FROM t_attachment WHERE FILE_ID IN (1,2,3)
,适用于表中该字段是int或者bigint类型,不适用于varchar。如果该字段是varchar类型,则正确的sql语句应该是:DELETE FROM t_attachment WHERE FILE_ID IN ("1","2","3");
map中就应该这样定义了:
数组/集合 -->(1,2,3,4)
String userIdList = formData.get("userIdList"); String[] users = userIdList.split(","); String str = ""; for (String user : users) { str += "\"" + user + "\"" + ","; } String substring = str.substring(0, str.lastIndexOf(",")); System.out.println(substring);
如果要传substring进sql语句中,但是substring不是数据库表中的字段,
三种方法:
① map.put("substring",substring),sql接收参数parameterType传java.util.Map
② 将substring放入对象中,传对象进去
③ 使用@Param("substring")注解
int deleteByCheckoutId(@Param("checkoutIdList") String checkoutIdList);
而int deleteByCheckoutId(long cDetailId);
不需要注解是因为cDetailId对应表中的C_DETAIL_ID,因为是表中现存的所以可以不用加,我个人理解。
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from t_checkout_detail
where C_DETAIL_ID = #{cDetailId,jdbcType=BIGINT}
</delete>
3、多参数批量删除示例
如果删除不是以主键为条件,而是多个条件同时成立才可以删除
<delete id="deleteByUserIdSysRoleBatch">
delete from t_user_role
where SYSCODE = #{sysCode,jdbcType=VARCHAR} AND ROLE_ID = #{roleId,jdbcType=VARCHAR} AND USER_ID IN
<foreach collection="userIds" item="item" index="index" open="(" separator="," close=")"> #{item} </foreach> </delete>
control层接口
@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseObj<Boolean> setMoreUserToRole(@RequestBody Map<String, String> formData) { String userIdList = formData.get("userIdList"); String[] users = userIdList.split(","); String str = ""; for (String user : users) { str += "\"" + user + "\"" + ","; } String substring = str.substring(0, str.lastIndexOf(",")); System.out.println(substring); String sysCode = formData.get("sysCode"); String roleId1 = formData.get("roleId"); userRoleMapper.deleteByUserIdSysRoleBatch(sysCode, roleId1, users); List<UserRole> list = new ArrayList<>(); for (int i = 0; i < users.length; i++) { UserRole userRole = new UserRole(); String roleId = formData.get("roleId"); if (roleId != null && !"".equals(roleId)) { userRole.setRoleId(roleId); } userRole.setStatus(SysData.STATUS_NORMAL); userRole.setOperateTime(DateUtil.getDateTime()); userRole.setOperator(formData.get("operator")); userRole.setSysCode(formData.get("sysCode")); userRole.setId(CommonUtil.getSysRef()); userRole.setUserId(users[i]); list.add(userRole); } int i = userRoleMapper.addByBatch(list); if (i == users.length) return new ResponseObj<Boolean>(true, RetCode.SUCCESS); return new ResponseObj<Boolean>(false, RetCode.FAIL); }
int deleteByUserIdSysRoleBatch(@Param("sysCode") String sysCode,
@Param("roleId") String roleId,
@Param("userIds") String[] userId);
上述collection的值为ids,是传入的参数Map的key
批量查询
1、orderList可以使用map/String传入
<select id="selectOrder" parameterType="java.util.Map" resultMap="OrderMap">
SELECT * FROM t_ WHERE ORDER_ID in (${orderList}) </select>
①对于表中的主键是bigint / int
==> Preparing: SELECT * FROM t_order WHERE ORDER_ID in (?)
==> Parameters: 1,2,5(String) <== Columns: ORDER_ID, GOODS_ID, UNIT_PRICE, SOLD_NUM, ORDER_STATUS, OPERATOR, OPERATE_TIME <== Row: 1, 356346093, 43.00, 3, 109002, yyadmin, 2017-12-16 21:01:20.0 <== Total: 1
注意"1,2,5"传过来的是String类型,实际sql语句如下:SELECT * FROM t_order WHERE ORDER_ID in (#{orderList})
SELECT * FROM t_order WHERE ORDER_ID in ('1,2,5')
只能查到一条
将mapper.xml中的sql语句改为SELECT * FROM t_order WHERE ORDER_ID in (${orderList})
SELECT * FROM t_order WHERE ORDER_ID in (1,2,5)
就可以全部查到。
②对于表中的主键是varcharSELECT * FROM t_order WHERE ORDER_ID in (#{orderList})
SELECT * FROM t_order WHERE ORDER_ID in ('1,2,5')
查询不到
将mapper.xml中的sql语句改为SELECT * FROM t_order WHERE ORDER_ID in (${orderList})
SELECT * FROM t_order WHERE ORDER_ID in ('1','2','5')
就可以全部
'1,2,5'转为'1','2','5'步骤如下:
String categoryIdList = (String) formData.get("categoryIdList");
if (!StringUtils.isEmpty(categoryIdList)) {
String[] split = categoryIdList.split(","); String sqlParamter = ""; for (String s : split) { sqlParamter += "'" + s + "',"; } String substring = sqlParamter.substring(0, sqlParamter.length() - 1); formData.put("categoryIdList", substring); }