mysql 的saveOrUpdate语句,实现批量新增或修改

建表语句

CREATE TABLE `kx_user_portfolio` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `portfolio_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

mybatis 写法


        INSERT INTO kx_user_portfolio
        ( id , portfolio_id , user_id)
        SELECT * FROM (
        
            SELECT
            #{item.id} as id , #{item.portfolioId} as portfolio_id , #{item.userId} as user_id FROM DUAL
        
        ) t2 on duplicate KEY UPDATE
        portfolio_id=t2.portfolio_id , user_id=t2.user_id
    

翻译成SQL语句

INSERT INTO kx_user_portfolio ( id, portfolio_id, user_id ) 
SELECT
* 
FROM
( SELECT 5 AS id, 77 AS portfolio_id, 33 AS user_id FROM DUAL UNION
SELECT NULL AS id, 33 AS portfolio_id, 44 AS user_id  FROM DUAL
) t2 ON DUPLICATE KEY UPDATE portfolio_id = t2.portfolio_id,
user_id = t2.user_id

-- 批量插入时,如果存在,这更新 portfolio_id user_id 这两个字段的值,其他不更新
-- 需要注意 如果id为null的时候,其他值也一样的话,只会有一条写入
-- 如果上述语句是更新操作和写入操作的话,受影响的行数,会是3,实质是,先写入时,主键约束失败1,更新1 第二条语句写入1 总计3
-- DUAL 关键字,表示虚表,mysql 也可以不指定,如:select now() ==> select now() from DUAL

附带python 测试脚本

import pymysql


def batch_save_or_update(connection, data_list):
    """
    批量保存或更新 kx_user_portfolio 表中的数据。

    :param connection: pymysql 数据库连接对象
    :param data_list: 包含字典的列表,每个字典表示一条记录,格式如下:
                      [{'id': 1, 'portfolioId': 101, 'userId': 1001}, ...]
    """
    try:
        if not data_list:
            print("数据列表为空,无法执行操作。")
            return

        # 构建 SQL 语句
        sql = """
        INSERT INTO kx_user_portfolio (id, portfolio_id, user_id)
        VALUES {}
        ON DUPLICATE KEY UPDATE
        portfolio_id = VALUES(portfolio_id),
        user_id = VALUES(user_id)
        """

        # 构建 VALUES 部分
        values = []
        for item in data_list:
            values.append(f"({item['id']}, {item['portfolioId']}, {item['userId']})")

        # 拼接完整 SQL
        sql = sql.format(", ".join(values))
        print(sql)
        # 执行 SQL
        with connection.cursor() as cursor:
            cursor.execute(sql)
            connection.commit()
            print(f"成功插入或更新 {cursor.rowcount} 条记录。")

    except pymysql.MySQLError as e:
        print(f"数据库操作失败:{e}")
        connection.rollback()
    finally:
        connection.close()


# 示例使用
if __name__ == "__main__":
    try:
        # 创建数据库连接
        connection = pymysql.connect(
            host="localhost",
            user="root",
            password="wonderful2021",
            database="demo",
            charset="utf8mb4"
        )

        # 示例数据
        data_list = [
            {'id': 1, 'portfolioId': 101, 'userId': 1001},
            {'id': 2, 'portfolioId': 1055, 'userId': 10055},
            {'id': 3, 'portfolioId': 103, 'userId': 1003}
        ]

        # 调用函数
        batch_save_or_update(connection, data_list)

    except pymysql.MySQLError as e:
        print(f"数据库连接失败:{e}")
    finally:
        if connection and connection.open:
            connection.close()
            print("数据库连接已关闭。")

你可能感兴趣的:(mysql,adb,数据库)