MyBatisforeach批量更新实例
在做配置选项(设备类型,所属楼层等)的时候,当删除某配置的时候,我需要检验该配置是否已被删除。
@Override
public BaseVO deleteOptionDetail(Integer id) {
// 合法性验证
if (null == id) {
Instance();
}
ConfigOptionDetail configOptionDetail = configOptionDetailMapper.selectById(id);
if (null == configOptionDetail || 1 == IsDeleted()) {
return new ErrorVO("该配置不存在");
}
if (System() == 1) {
return new ErrorVO("系统属性不能删除");
}
if (UseCount() = 0) {
return new ErrorVO("配置正在使⽤不能删除,请先删除使⽤配置的地⽅");
}
// 合法性通过
configOptionDetail.setIsDeleted(1);
configOptionDetail.Instance().getTime());
configOptionDetailMapper.updateById(configOptionDetail);
/
/ 更新内存配置
ConfigOptionConstruct.updateOption();
Instance();
}
思考之后我决定采⽤,给配置选项设备⼀个use_count字段,代表该配置被引⽤的次数。只有当该字段值为 0 时,该配置选项记录才可被删除。
使⽤情况:
我需要批量删除房间,删除房间的同时,room对象中使⽤到了所属楼层的配置选项,我需要将他们的引⽤减少
@Override
public BaseVO deleteRoomByIds(Integer[] ids) {
if (null == ids) {
Instance();
}
EntityWrapper<Room> entityWrapper = new EntityWrapper<>();
entityWrapper.where("isdelete={0}", 0);
// 核查删除的房间中是否存在正在使⽤的设备
List<Integer> notDelete = deviceInfoService.checkRoomIds(ids);
if (null != notDelete && 0 != notDelete.size()) {
// 存在仍在使⽤设备的房间
entityWrapper.in("id", notDelete);
// 查询这些房间
List<Room> roomList = roomMapper.selectList(entityWrapper);
// 获取房间的名称
StringBuilder stringBuilder = new StringBuilder(roomList.stream().map(Room::getName).List()).toString());
System.out.println(stringBuilder);
// TODO: 2018/4/8 可能需要修改提⽰语
return new ErrorVO(stringBuilder + " 房间存在未删除的设备,请先删除设备");
}
// 房间没有设备在使⽤
List<Integer> idList = new ArrayList<>();
idList.addAll(Arrays.asList(ids));
// 查询需要删除的房间
entityWrapper.in("id", idList);
List<Room> roomList = roomMapper.selectList(entityWrapper);
if (null == roomList || idList.size() != roomList.size()) {
return new ErrorVO("存在错误的房间");
}
// ******************************************************************************************** 重点
// 可以逻辑删除
int count = roomMapper.logicDeleteByIds(idList);
List<Long> optionIds = roomList.stream().map(room -> Long.RoomPosition())).List());
Map<Long, Long> optionIdsMap = optionIds.stream().upingBy(p -> unting()));
// 移除所属楼层配置选项的使⽤
ConfigOptionConstruct.updateOption();
if (count == idList.size()) {
Instance();
} else {
return new ErrorVO("部分删除失败");
}
}
optionIds 是从roomList 房间集合中,通过stream, 所引⽤的配置选项id集合
上⾯我红字标明他们,是因为,如果房间A 是⼀楼,房间B 也是⼀楼,那么我应该将⼀楼的引⽤减 2。
所以我将optionIds 分组转成Map<;配置选项id,需要减少引⽤的次数>
最后⼀步,也是最重要的进⾏数据库操作,我希望可以批量更新减少这些引⽤。
查看MyBatis⽂档:
foreach
动态 SQL 的另外⼀个常⽤的操作需求是对⼀个集合进⾏遍历,通常是在构建 IN 条件语句的时候。⽐如:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach 元素的功能⾮常强⼤,它允许你指定⼀个集合,声明可以在元素体内使⽤的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。
注意你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。当使⽤可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使⽤ Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
<update id="addUseCountByIds">
update config_option_detail
set gmt_modified = #{gmtModified}, use_count = use_count +
<foreach item="item" index="index" collection="list" open=" case id " separator=" " close=" end">
when #{index} then #{item}
</foreach>
where id in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{index}
</foreach>
</update>
补充:mybatis ⽤<foreach>根据ID批量更新时的⼀个注意点。
看接⼝。传⼊⼀个Long型的List。
int updateReadCount(@Param(value = "topicIdList") List<Long> topicIdList);
xml⾥⾯循环update.
<update id="updateReadCount" parameterType="java.util.List">
update CTS
set read_count = read_count + 1
where topic_id in
<foreach item="item" index="index" collection="topicIdList" open="(" close=")" separator=",">
#{picId}
</foreach>
</update>
就是直接复制了别⼈的代码,改了⼀改。怎么都跑不通。。。。。。。
问题就出在这个item,item 表⽰集合中每⼀个元素进⾏迭代时的别名。
delete inList<Long> topicIdList 因为时Long型(不是entity封装着的),就不需要别名了。改为如下就可以跑通了。
<update id="updateReadCount" parameterType="java.util.List">
update CTS
set read_count = read_count + 1
where topic_id in
<foreach item="topicId" index="index" collection="topicIdList" open="(" close=")" separator=",">
#{topicId}
</foreach>
</update>
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。如有错误或未考虑完全的地⽅,望不吝赐教。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论