merge into结合sql批处理用法

场景

我们平常工作中一般都会有这样一个场景,我往数据库插入一条记录,如果该条记录已经存在,那么只需要更新;如果不存在,则直接插入。通常的做法就是,在插入这条数据之前,我先去数据库里查下该记录是否存在,然后再决定我是做insert操作还是update操作。这样一来,数据库就操作了两次,有木有更好的办法?

我接到一个任务,将一个list集合里面的数据一次性插入到A表里,并且如果A表有重复记录则更新;反之,则插入。很显然,这要用到批处理,并且我需要拿到list里的所有元素去跟数据库比对,刷选出哪些是重复,哪些是新增。这样实现的结果代码不简洁,性能也不高。

merge into 用法

有了merge into之后,事情就变得简单多了。

<insert id="insertOrUpdate" parameterType="cn.com.ft.meta.bean.NfxMetaYwb">
    MERGE INTO Tab_A T1
    USING (SELECT #{ywbId,jdbcType=VARCHAR} YWB_ID,
                  #{ywbms,jdbcType=VARCHAR} YWBMS,
                  #{cjmc,jdbcType=VARCHAR} CJMC,
                  #{fxdxlb,jdbcType=VARCHAR} FXDXLB,
                  #{cjId,jdbcType=VARCHAR} CJ_ID,
                  #{yxbz,jdbcType=VARCHAR} YXBZ
             FROM dual) T2
    on (T1.YWB_ID = T2.YWB_ID)
    WHEN MATCHED THEN
      UPDATE
         SET T1.YWBMS  = T2.YWBMS,
             T1.CJMC   = T2.CJMC,
             T1.FXDXLB = T2.FXDXLB,
             T1.CJ_ID  = T2.CJ_ID,
             T1.YXBZ   = T2.YXBZ
    WHEN NOT MATCHED THEN
      INSERT
        (T1.YWB_ID, T1.YWBMS, T1.CJMC, T1.FXDXLB, T1.CJ_ID, T1.YXBZ)
      VALUES
        (T2.YWB_ID, T2.YWBMS, T2.CJMC, T2.FXDXLB, T2.CJ_ID, T2.YXBZ)
</insert>

select语句就是查询list集合里的元素,采用 FROM dual 虚拟表的形式保证能从数据库查出一条记录来,其实查出来的记录就是参数list集合里的一个元素(T2来自list集合数据组成的临时表,T1是真实需要插入或更新的表)。通过on将两个表关联起来,后面如果重复,会执行update,将T2的数据更新到T1;如果是新记录,则执行insert,将T2的数据插入到T1。这样一来,我们不需要再去过多关注sql语句是insert还是update,只需要注重后台的调用即可。

后台批处理运用

public int saveFxys(String ywbId, List<FxysDto> fxysList) {
    //需要在获得session的时候指定批处理模式
    SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
    NfxMetaFxysMapper fxysMapper = session.getMapper(NfxMetaFxysMapper.class);

    try {
        if (!CollectionUtils.isEmpty(fxysList)) {
            //每遍历一条记录,就组装一个insert语句
            for (FxysDto fxysDto : fxysList) {
                NfxMetaFxys nfxMetaFxys = new NfxMetaFxys();
                nfxMetaFxys.setYsid(fxysDto.getId());
                nfxMetaFxys.setYwbId(ywbId);
                nfxMetaFxys.setYsdm(fxysDto.getCode());
                ... ...
                    //这里每遍历一条记录,就赋值给 merge into 那里的T2
                    fxysMapper.insertOrUpdate(nfxMetaFxys);
            }
            //最终一并提交事务
            session.commit();
            return 1;
        } 
    } catch (Exception e) {
        log.error(e.getMessage(), e);
        e.printStackTrace();
        session.rollback();
    } finally {
        if (session != null) {
            session.close();
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值