MySql -- 不存在则插入,存在则更新或忽略

Posted 普通网友

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql -- 不存在则插入,存在则更新或忽略相关的知识,希望对你有一定的参考价值。

1.前言

mysql在插入数据时,需要忽略或替换掉重复的数据(依据某个字段,比如Primary Key或

Unique Key来确定是否重复),这时候我们既可以在应用层处理,也可以使用复杂的 SQL 语句来处理(如果仅仅知道一些简单的 SQL 语法的话),当然也可以使用一些简单的 SQL 语法,不过它并不是通用所有的数据库类型。

下面我们以MySQL为例,研究一下insert 怎样去忽略或替换重复数据

2.表实例

表名称:person

表字段:

Column Name

Primary Key

Auto Increment

Unique

id

true

true

name

true

age

初始表数据:

id

name

age

111

Bruce

36

3.三个简单例子:

Note:本文的3个例子都需要被插入的表中存在UNIQUE索引PRIMARY KEY字段

1. 不存在则插入,存在则更新

1.1 on duplicate key update

如果插入的数据会导致UNIQUE 索引PRIMARY KEY发生冲突/重复,则执行UPDATE语句,例:

INSERT INTO `person`(`name`, `age`) VALUES(‘Bruce’, 18)
ON DUPLICATE KEY
UPDATE `age`=19; – If will happen conflict, the update statement is executed

– 2 row(s) affected

这里受影响的行数是2,因为数据库中存在name='Bruce'的数据,如果不存在此条数据,则受影响的行数为1。

最新的表数据如下:

id

name

age

1

Bruce

18

1.2 replace into

如果插入的数据会导致UNIQUE 索引PRIMARY KEY发生冲突/重复,则先删除旧数据再插入最新的数据,例:

REPLACE INTO `person`(`name`, `age`) VALUES(‘Bruce’, 20);

– 2 row(s) affected

这里受影响的行数是2,因为数据库中存在name='Jack'的数据,并且id的值会变成2,因为它是先删除旧数据,然后再插入数据,最新的表数据如下:

id

name

age

2

Bruce

20

2. 避免重复插入(存在则忽略)

关键字/句:insert ignore into,如果插入的数据会导致UNIQUE索引PRIMARY KEY发生冲突/重复,则忽略此次操作/不插入数据,例:

INSERT IGNORE INTO `person`(`name`, `age`) VALUES(‘Bruce’, 18);

– 0 row(s) affected

这里已经存在name='Bruce'的数据,所以会忽略掉新插入的数据,受影响行数为0,表数据不变。

4.三个复杂例子:

我们可以用customerMobile字段作为唯一索引(UNIQUE 索引)

Mapper类:

package com.example.springbootmybatisplusbruce.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springbootmybatisplusbruce.model.E**Customer;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface E**CustomerMapper extends BaseMapper<E**Customer> 

    /**
     *  不存在则插入,存在则更新
     * on duplicate key update: 如果插入的数据会导致UNIQUE 索引或PRIMARY KEY发生冲突/重复,则执行UPDATE语句
     * @param e**Customer
     * @return
     */
    public int insertDuplicateKeyUpdate(E**Customer e**Customer);

    /**
     * replace into: 如果插入的数据会导致UNIQUE索引 或 PRIMARY KEY 发生冲突/重复,则先删除旧数据,再插入最新的数据
     * @param etcCustomer
     * @return
     */
    public int insertReplaceInto(E**Customer e**Customer);

    /**
     * 避免重复插入
     * insert ignore into: 如果插入的数据会导致UNIQUE索引或PRIMARY KEY发生冲突/重复,则忽略此次操作/不插入数据
     * @param e**Customer
     * @return
     */
    public int insertIgnore(E**Customer e**Customer);

xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springbootmybatisplusbruce.mapper.E**CustomerMapper">

    <resultMap type="com.example.springbootmybatisplusbruce.model.E**Customer" id="E**CustomerResult">
        <result property="id"    column="id"    />
        <result property="customerType"    column="customer_type"    />
        <result property="customerName"    column="customer_name"    />
        <result property="customerMobile"    column="customer_mobile"    />
        .......................................................................
    </resultMap>

    <sql id="selectE**CustomerVo">
        select id, customer_type, customer_name, customer_mobile,
...........................................................................
from etc_customer
    </sql>
    <!-- 不存在则插入,存在则更新 -->
    <!-- on duplicate key update: 如果插入的数据会导致UNIQUE 索引或PRIMARY KEY发生冲突/重复,则执行UPDATE语句 -->
    <insert id="insertDuplicateKeyUpdate" parameterType="com.example.springbootmybatisplusbruce.model.E**Customer">
        INSERT INTO e**_customer(id, customer_type, customer_name, customer_mobile, credential_type, credential_no, status, del_flag, create_by, create_time, update_by, update_time, remark)
            VALUES(#id, #customerType, #customerName, #customerMobile, #credentialType, #credentialNo, #status, #delFlag, #createBy, #createTime, #updateBy, #updateTime, #remark)
            ON DUPLICATE KEY
            UPDATE
            <if test="customerType != null">customer_type=#customerType,</if>
            <if test="customerName != null  and customerName != ''">customer_name=#customerName,</if>
            <if test="customerMobile != null  and customerMobile != ''">customer_mobile=#customerMobile,</if>
            <if test="credentialType != null">credential_type=#credentialType,</if>
            <if test="credentialNo != null  and credentialNo != ''">credential_no=#credentialNo,</if>
            <if test="status != null">status=#status</if>
    </insert>

    <!-- replace into: 如果插入的数据会导致UNIQUE索引 或 PRIMARY KEY 发生冲突/重复,则先删除旧数据再插入最新的数据 -->
    <insert id="insertReplaceInto">
        REPLACE INTO e**_customer(id, customer_type, customer_name, customer_mobile, credential_type, credential_no, status, del_flag, create_by, create_time, update_by, update_time, remark)
        VALUES(#id, #customerType, #customerName, #customerMobile, #credentialType, #credentialNo, #status, #delFlag, #createBy, #createTime, #updateBy, #updateTime, #remark)
    </insert>

    <!-- 避免重复插入 -->
    <!-- insert ignore into: 如果插入的数据会导致UNIQUE索引或PRIMARY KEY发生冲突/重复,则忽略此次操作/不插入数据 -->
    <insert id="insertIgnore">
        INSERT IGNORE INTO e**_customer(id, customer_type, customer_name, customer_mobile, credential_type, credential_no, status, del_flag, create_by, create_time, update_by, update_time, remark)
        VALUES(#id, #customerType, #customerName, #customerMobile, #credentialType, #credentialNo, #status, #delFlag, #createBy, #createTime, #updateBy, #updateTime, #remark)
    </insert>
</mapper>

service类:

package com.example.springbootmybatisplusbruce.service;

import com.example.springbootmybatisplusbruce.mapper.ETCCustomerMapper;
import com.example.springbootmybatisplusbruce.model.EtcCustomer;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;

@Service
public class FTPFileParseService 

    @Autowired
    private E**CustomerMapper e**CustomerMapper;

    /**
     * 参考文章:https://blog.csdn.net/t894690230/article/details/77996355
     *         https://blog.csdn.net/weixin_45607513/article/details/117470118
     * @throws IOException
     */
    @Transactional(rollbackFor = Exception.class)
    public void fileParse() throws IOException 
        StringBuilder result = new StringBuilder();
        String path = "F:\\Digital marketing\\E** system\\txt-from-ftp\\20210302_VEHICLE.txt";

        long start = System.currentTimeMillis(); //程序执行前的时间戳
        BufferedReader br = new BufferedReader(new FileReader(path));//构造一个BufferedReader类来读取文件
        String line = null;
        while((line = br.readLine())!=null)//使用readLine方法,一次读一行
//            result.append(System.lineSeparator()+s);
            System.out.println("Debug:" + line);
            String [] infoArray = line.split("@~@");
            EtcCustomer e**Customer = new EtcCustomer();
            if(infoArray[0].isEmpty())continue;
            e**Customer.setId(Long.valueOf(infoArray[0]).longValue());
            e**Customer.setCustomerType(Long.valueOf(infoArray[4]).longValue());
            e**Customer.setCustomerName(infoArray[2]);
            e**Customer.setCustomerMobile(infoArray[3]);
            e**Customer.setCredentialType(Long.valueOf(infoArray[5]).longValue());
            e**Customer.setCredentialNo(infoArray[6]);
            e**Customer.setStatus(Long.valueOf(infoArray[15]).longValue());
            e**Customer.setDelFlag(0L);

            //on duplicate key update: 如果插入的数据会导致UNIQUE 索引或PRIMARY KEY发生冲突/重复,则执行UPDATE语句
//            e**CustomerMapper.insertDuplicateKeyUpdate(etcCustomer);

            //insert ignore into: 如果插入的数据会导致UNIQUE索引或PRIMARY KEY发生冲突/重复,则忽略此次操作/不插入数据
            e**CustomerMapper.insertIgnore(etcCustomer);

            //replace into: 如果插入的数据会导致UNIQUE索引 或 PRIMARY KEY 发生冲突/重复,则先删除旧数据,再插入最新的数据
//          e**CustomerMapper.insertReplaceInto(etcCustomer);
        
        br.close();
        long end = System.currentTimeMillis(); //程序执行后的时间戳
        System.out.println("程序执行花费时间:" + (end - start));
    



先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

sql:mysql:MySql 不存在则插入,存在则更新或忽略

前言

在插入数据时,可能需要忽略或替换掉重复的数据(依据某个字段),这时可以在应用层处理,也可以使用复杂的 SQL 语句来处理(如果仅仅知道一些简单的 SQL 语法的话),当然也可以使用一些简单的 SQL 语法,不过它并不是通用所有的数据库类型。

以下所有实例仅针对MySQL而言,并不能随意用于其它数据库

以下的表建的唯一索引,无论一个或多个,只要导致任何一个 UNIQUE 索引PRIMARY KEY发生冲突/重复,都适用。

实例

表名称:student

表字段:

Column NamePrimary KeyAuto IncrementUnique
idtruetrue 
name  true
age   

初始表数据:

idnameage
1Jack18

注:以下所有的示例都需要被插入的数据中需要存在UNIQUE索引PRIMARY KEY字段,同时这里引入表的主键id,并设置成自动递增,后面可以看到它的变化

1. 不存在则插入,存在则更新(插入或可指定更新个别字段)

1.1 on duplicate key update

如果插入的数据会导致UNIQUE 索引PRIMARY KEY发生冲突/重复,则执行UPDATE语句,例:

INSERT INTO `student`(`name`, `age`) VALUES('Jack', 19)
  ON DUPLICATE KEY 
  UPDATE `age`=19; -- If will happen conflict, the update statement is executed

-- 2 row(s) affected

这里受影响的行数是2,因为数据库中存在name='Jack'的数据,如果不存在此条数据,则受影响的行数为1

最新的表数据如下:

idnameage
1Jack19

1.2 replace into(插入或直接更新为最新的记录)

如果插入的数据会导致UNIQUE 索引PRIMARY KEY发生冲突/重复,则先删除旧数据再插入最新的数据(注意未指定的字段可能被插入空值),例:

REPLACE INTO `student`(`name`, `age`) VALUES('Jack', 18);

-- 2 row(s) affected

这里受影响的行数是2,因为数据库中存在name='Jack'的数据,并且id的值会变成2,因为它是先删除旧数据,然后再插入数据,最新的表数据如下:

idnameage
2Jack19

2. insert ignore into 避免重复插入

关键字/句:insert ignore into,如果插入的数据会导致UNIQUE索引PRIMARY KEY发生冲突/重复,则忽略此次操作/不插入数据,例:

INSERT IGNORE INTO `student`(`name`, `age`) VALUES('Jack', 18);

-- 0 row(s) affected

这里已经存在name='Jack'的数据,所以会忽略掉新插入的数据,受影响行数为0,表数据不变。

以上。

 

以上是关于MySql -- 不存在则插入,存在则更新或忽略的主要内容,如果未能解决你的问题,请参考以下文章

sql:mysql:MySql 不存在则插入,存在则更新或忽略

MySQL:数据存在则更新,不存在则插入

MySQL插入更新_ON DUPLICATE KEY UPDATE

Mysql插入数据:不存在则插入,存在则跳过或更新

如果 mysql 数据库中的表中不存在,则更新或插入多条记录

将MYSQL某一数据库中的多条记录批量插入到另一MYSQL数据库时,记录不存在则插入,存在则更新