on duplicate key update的使用

文章讲述了在Java开发中如何利用MySQL的`onduplicatekeyupdate`特性,配合Java实体类和分批导入策略,高效处理用户信息表的插入与更新,避免重复数据。重点讨论了主键选择、索引创建以及控制层和服务层的具体实现。

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

目录

实体类

控制层

服务层

数据层


在开发中经常会遇到操作数据库时若库中存在则更新,不存在则插入的需求。若是一条一条的查询判断那不得累死啊!在mysql中有 on duplicate key update的语句支持!

实体类

注意此user表中主键为uid,所以在新增修改时会根据uid主键查询;

若主键为id,需要根据某列的值进行新增修改判断唯一值;则需要创建索引;比如考勤信息中,表中有id,uid,fadate(打卡日期)需要以工号、考勤信息为组合索引,在导入时判断 某日期某工号是否已存在,存在则更新,不存在则插入!

/**
 * 用户信息表
 *
 * @author chensir
 * @date 2024/4/16
 */
@Data
@Builder
@TableName("user_info")
@AllArgsConstructor
@NoArgsConstructor
public class UserInfoEntity extends BaseEntity {

    /**
     * 工号
     */
    @TableId(value = "uid")
    private String uid;
    /**
     * 姓名
     */
    private String name;
    /**
     * 性别
     */
    private String sex;
    /**
     * 电话
     */
    private String tel;
    /**
     * 邮箱
     */
    private String email;
    /**
     * 部门名称
     */
    private String deptName;
    /**
     * 岗位名称
     */
    private String postName;
    /**
     * 加班控制码 T000固薪制
     */
    private String jbkzm;
    /**
     * 职系
     */
    private String grades;
    /**
     * 领导工号
     */
    private String leaderUid;
    /**
     * 领导姓名
     */
    private String leaderName;
    /**
     * 入职日期
     */
    private LocalDate entryTime;
    /**
     * 状态 0在职 1离职
     */
    private String status;
    /**
     * 离职日期
     */
    private LocalDate dimissionTime;

    private Integer sort;

    @TableLogic
    private String delFlag;
}

控制层

 @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
        ExcelResult<UserInfoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), UserInfoImportVo.class, true);
        userInfoService.importBatch(excelResult.getList());
        return R.ok(excelResult.getAnalysis());
    }

服务层

 void importBatch(List<UserInfoImportVo> list);




@Override
    @Transactional(rollbackFor = Exception.class)
    public void importBatch(List<UserInfoImportVo> boList) {
        // 校验excel中是否有重复数据
        List<String> res = new ArrayList<>();
        List<UserInfoImportVo> voList = new ArrayList<>();
        boList.forEach(user -> {
            if (res.contains(user.getUid())) {
                throw new HraException("Excel中有重复的信息,请检查工号为:" + user.getUid() + "的数据!");
            }
         
            user.setCreateBy(LoginHelper.getLoginUser().getUsername());
            user.setCreateName(LoginHelper.getLoginUser().getNickname());
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateBy(LoginHelper.getLoginUser().getUsername());
            user.setUpdateName(LoginHelper.getLoginUser().getNickname());
            user.setUpdateTime(LocalDateTime.now());
            res.add(user.getUid());
            voList.add(user);
        });


        int batchSize = 1500;
        for (int i = 0; i < voList.size(); i += batchSize) {
//            userInfoMapper.resetAutoIncrement();
            List<UserInfoImportVo> batch = voList.subList(i, Math.min(voList.size(), i + batchSize));
            userInfoMapper.batchUpsertPurtable(batch);
        }
    }

数据层

void batchUpsertPurtable(@Param("query") List<UserInfoImportVo> batch);


<insert id="batchUpsertPurtable">
        insert into user_info(
        uid,
        name,
        sex,
        tel,
        email,
        dept_name,
        post_name,
        jbkzm,
        grades,
        leader_uid,
        leader_name,
        entry_time,
        status,
        dimission_time,
        create_by,
        create_name,
        create_time,
        update_by,
        update_name,
        update_time
        ) values
        <foreach collection="query" separator="," item="item">
            (
            #{item.uid},
            #{item.name},
            #{item.sex},
            #{item.tel},
            #{item.email},
            #{item.deptName},
            #{item.postName},
            #{item.jbkzm},
            #{item.grades},
            #{item.leaderUid},
            #{item.leaderName},
            #{item.entryTime},
            #{item.status},
            #{item.dimissionTime},
            #{item.createBy},
            #{item.createName},
            #{item.createTime},
            #{item.updateBy},
            #{item.updateName},
            #{item.updateTime}
            )
        </foreach>
        on duplicate key update
        sex= values(sex),
        tel= values(tel),
        email= values(email),
        dept_name= values(dept_name),
        post_name= values(post_name),
        jbkzm= values(jbkzm),
        grades= values(grades),
        leader_uid= values(leader_uid),
        leader_name= values(leader_name),
        entry_time= values(entry_time),
        status= values(status),
        dimission_time= values(dimission_time)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值