如何将两个写入数据库的函数整合成一个?
- 内容介绍
- 文章标签
- 相关推荐
话说回来,

# 多数据源支持:
统一返回结构:让上层业务只关心

事务一致性:所有写操作放在同一事务块内。出现异常时立即回滚,确保数据完整性。
日志与监控:在异常捕获处统一记录错误日志。并结合 APM 工具监控执行时间,以便快速定位性能瓶颈。
在主要函数里依据主键是否存在决定执行="" (>定义统一的数据模型,让所有字段一次性传递。)="" (>统一异常捕获与事务提交="" (>配合日志=""
在实际项目中。经常会遇到需要分别编写 INSERT 与 UPDATE 两个函数来完成数据写入和更新的情况。这种做法虽然直观,却隐藏着一系列让开发者头疼的问题:
- 代码冗余两套几乎相同的连接、事务、异常处理逻辑不断复制粘贴。
- 维护成本高一处改动需要同步到两个函数,容易出现遗漏导致 bug。
- 多数据源切换困难项目涉及多个库时需要在每个函数里额外处理数据源切换逻辑。
- 一致性难保障不同函数使用不同的错误日志或返回格式,导致上层调用方需做额外适配。老实说,
一、常见的数据库写入函数概述
1. INSERT 函数
至于基本语法。
INSERT INTO 表名 VALUES;
2. UPDATE 函数
UPDATE 表名 SET 列1=值1。列2=值2,... WHERE 条件表达式;
二、痛点深度剖析
- 重复的连接与事务代码每个函数都要创建连接、打开游标、提交事务,再关闭资源。
- 错误处理不统一一个函数捕获异常后返回布尔值。另一个返回错误信息,导致业务层判断繁琐。
- 硬编码的表名/列名当表结构变化时需要逐个修改两个地方。
- 多库环境下的数据源配置混乱在 Spring Boot 的 yml 中配置多个 dataSource 时每个函数都要显式指定使用哪一个。
三、整合思路——建立统一的写入入口
通过以下几个步骤即可把 INSERT 与 UPDATE 合并为一个通用函数:
- 统一参数结构:使用一个数据对象封装所有列值,并提供可选的主键字段用于判断是插入还是更新。
- 内部区分操作类型:If 主键为空 → 执行 INSERT;否则 → 执行 UPDATE。
- 抽象数据库连接层:`get_connection` 根据配置返回对应的数据源,实现多库透明切换。
-
统一异常与事务管理:`try…except` 块一次性完成提交或回滚,并统一返回 `
{'success': True/False。'msg': '...'}` 的字典。
四、实现示例
import pymysql
from dataclasses import dataclass
from typing import Optional
# ---------- 数据模型 ----------
@dataclass
class Student:
id这方面,Optional = None # 主键,None 表示插入
说到name,str = ''
age这方面,int = 0
从gender来看。str = ''
# ---------- 数据库连接抽象 ----------
def get_connection:
# 示例仅演示单库,实际项目可根据 yml 配置返回不同 DataSource
return pymysql.connect(
host='localhost',port=3306,user='root',password='password',database='mydb',charset='utf8mb4'
)
# ---------- 统一写入函数 ----------
def upsert_student:
"""
根据 student.id 判断是 INSERT 还是 UPDATE。返回统一结构 {'success': bool,'msg': str}
"""
conn = None
cursor = None
再看try,conn = get_connection
cursor = conn.cursor
if student.id is None:
# ----------- INSERT -----------
sql = """
INSERT INTO students
VALUES
"""
params =
cursor.execute
conn.commit
return {'success': True,'msg': f'Inserted ID {cursor.lastrowid}'}
说到else,# ----------- UPDATE -----------
sql = """
UPDATE students
SET name=%s,age=%s,gender=%s
WHERE id=%s
"""
params = (student.name,student.age,student.gender。
student.id)
affected = cursor.execute
conn.commit
return {'success': affected> 0,'msg': f'Updated rows {affected}'}
except Exception as e:
if conn:
conn.rollback
return {'success': False,'msg': f'Error: {e}'}
finally:
if cursor:
cursor.close
if conn:
conn.close
# ---------- 调用示例 ----------
# 插入新学生
new_student = Student
print)
# 更新已有学生
existing_student = Student(id=1,name='John Doe',age=21,gender='Male')
print)
五、关键要点 & 常用方法
- SQL 模板化:Python 中使用占位符 `%s` 防止 SQL 注入;在 Java / C# 等语言同理采用预编译语句。
- ID 判定原则:ID 为 `NULL` 或 `0` 时视为插入,其余视为更新;话说回来,业务层可自行约定更细粒度标识。
get_connection 可读取 Spring Boot 的 application.yml 中定义的 @Primary 与 @Qualifier 数据源,实现“一键切换”。
success 与 msg 两个字段,无需区分是插入还是更新产生的结果。话说回来,
六、常用 SQL 语句速查表
| 操作 | 示例 | 说明 |
|---|---|---|
| 插入单条记录 |
|
将一条新记录写入表中。 |
| 批量插入 |
|
一次性插入多条记录,提高写入效率。 |
| 更新单条记录 |
|
根据条件修改已有记录。 |
| 批量更新 |
|
一次性修改满足条件的多行。 |
| 删除记录 |
七、 & 行动教程
通过将 INSERT 与 UPDATE 合并为一个通用 “upsert” 函数。可以显著降低代码冗余、提高维护效率,并在多库环境下实现透明的数据源切换。坚持下面几点即可快速落地:
话说回来,

# 多数据源支持:
统一返回结构:让上层业务只关心

事务一致性:所有写操作放在同一事务块内。出现异常时立即回滚,确保数据完整性。
日志与监控:在异常捕获处统一记录错误日志。并结合 APM 工具监控执行时间,以便快速定位性能瓶颈。
在主要函数里依据主键是否存在决定执行="" (>定义统一的数据模型,让所有字段一次性传递。)="" (>统一异常捕获与事务提交="" (>配合日志=""
在实际项目中。经常会遇到需要分别编写 INSERT 与 UPDATE 两个函数来完成数据写入和更新的情况。这种做法虽然直观,却隐藏着一系列让开发者头疼的问题:
- 代码冗余两套几乎相同的连接、事务、异常处理逻辑不断复制粘贴。
- 维护成本高一处改动需要同步到两个函数,容易出现遗漏导致 bug。
- 多数据源切换困难项目涉及多个库时需要在每个函数里额外处理数据源切换逻辑。
- 一致性难保障不同函数使用不同的错误日志或返回格式,导致上层调用方需做额外适配。老实说,
一、常见的数据库写入函数概述
1. INSERT 函数
至于基本语法。
INSERT INTO 表名 VALUES;
2. UPDATE 函数
UPDATE 表名 SET 列1=值1。列2=值2,... WHERE 条件表达式;
二、痛点深度剖析
- 重复的连接与事务代码每个函数都要创建连接、打开游标、提交事务,再关闭资源。
- 错误处理不统一一个函数捕获异常后返回布尔值。另一个返回错误信息,导致业务层判断繁琐。
- 硬编码的表名/列名当表结构变化时需要逐个修改两个地方。
- 多库环境下的数据源配置混乱在 Spring Boot 的 yml 中配置多个 dataSource 时每个函数都要显式指定使用哪一个。
三、整合思路——建立统一的写入入口
通过以下几个步骤即可把 INSERT 与 UPDATE 合并为一个通用函数:
- 统一参数结构:使用一个数据对象封装所有列值,并提供可选的主键字段用于判断是插入还是更新。
- 内部区分操作类型:If 主键为空 → 执行 INSERT;否则 → 执行 UPDATE。
- 抽象数据库连接层:`get_connection` 根据配置返回对应的数据源,实现多库透明切换。
-
统一异常与事务管理:`try…except` 块一次性完成提交或回滚,并统一返回 `
{'success': True/False。'msg': '...'}` 的字典。
四、实现示例
import pymysql
from dataclasses import dataclass
from typing import Optional
# ---------- 数据模型 ----------
@dataclass
class Student:
id这方面,Optional = None # 主键,None 表示插入
说到name,str = ''
age这方面,int = 0
从gender来看。str = ''
# ---------- 数据库连接抽象 ----------
def get_connection:
# 示例仅演示单库,实际项目可根据 yml 配置返回不同 DataSource
return pymysql.connect(
host='localhost',port=3306,user='root',password='password',database='mydb',charset='utf8mb4'
)
# ---------- 统一写入函数 ----------
def upsert_student:
"""
根据 student.id 判断是 INSERT 还是 UPDATE。返回统一结构 {'success': bool,'msg': str}
"""
conn = None
cursor = None
再看try,conn = get_connection
cursor = conn.cursor
if student.id is None:
# ----------- INSERT -----------
sql = """
INSERT INTO students
VALUES
"""
params =
cursor.execute
conn.commit
return {'success': True,'msg': f'Inserted ID {cursor.lastrowid}'}
说到else,# ----------- UPDATE -----------
sql = """
UPDATE students
SET name=%s,age=%s,gender=%s
WHERE id=%s
"""
params = (student.name,student.age,student.gender。
student.id)
affected = cursor.execute
conn.commit
return {'success': affected> 0,'msg': f'Updated rows {affected}'}
except Exception as e:
if conn:
conn.rollback
return {'success': False,'msg': f'Error: {e}'}
finally:
if cursor:
cursor.close
if conn:
conn.close
# ---------- 调用示例 ----------
# 插入新学生
new_student = Student
print)
# 更新已有学生
existing_student = Student(id=1,name='John Doe',age=21,gender='Male')
print)
五、关键要点 & 常用方法
- SQL 模板化:Python 中使用占位符 `%s` 防止 SQL 注入;在 Java / C# 等语言同理采用预编译语句。
- ID 判定原则:ID 为 `NULL` 或 `0` 时视为插入,其余视为更新;话说回来,业务层可自行约定更细粒度标识。
get_connection 可读取 Spring Boot 的 application.yml 中定义的 @Primary 与 @Qualifier 数据源,实现“一键切换”。
success 与 msg 两个字段,无需区分是插入还是更新产生的结果。话说回来,
六、常用 SQL 语句速查表
| 操作 | 示例 | 说明 |
|---|---|---|
| 插入单条记录 |
|
将一条新记录写入表中。 |
| 批量插入 |
|
一次性插入多条记录,提高写入效率。 |
| 更新单条记录 |
|
根据条件修改已有记录。 |
| 批量更新 |
|
一次性修改满足条件的多行。 |
| 删除记录 |
七、 & 行动教程
通过将 INSERT 与 UPDATE 合并为一个通用 “upsert” 函数。可以显著降低代码冗余、提高维护效率,并在多库环境下实现透明的数据源切换。坚持下面几点即可快速落地:

