使用Rust Diesel插入数据时能否直接返回最新插入的记录?
Rust Diesel 插入操作直接返回完整记录的实现方法
核心结论
你不需要在插入后先获取ID再做二次查询,Diesel 1.4.8 版本搭配 PostgreSQL 可以直接在插入语句执行时一次性返回完整的插入记录,不需要额外的数据库请求。
你当前使用的execute方法仅用于执行无结果集返回的写操作,只会返回受影响的行数,替换为Diesel提供的结果返回方法即可实现需求。
实现方式
PostgreSQL 本身支持RETURNING语法可以返回插入/更新后的行数据,Diesel对该语法做了封装,只需要将链式调用末尾的execute替换为get_result(单条插入)或者get_results(批量插入),就可以直接拿到映射完成的结构体实例。
修改后的核心代码如下:
pub fn add_bill_book(request: &Json<BillBookRequest>, login_user_info: &LoginUserInfo) -> BillBook { let connection = config::connection("FORTUNE_DATABASE_URL".to_string()); let bill_book_record = BillBookAdd{ created_time: get_current_millisecond(), updated_time: get_current_millisecond(), deleted: 0, creator: login_user_info.userId, remark: None, bill_book_template_id: request.billBookTemplateId, contents: None }; // 替换execute为get_result,直接拿到插入后的完整记录 let inserted_bill_book: BillBook = diesel::insert_into(crate::model::diesel::fortune::fortune_schema::bill_book::table) .values(&bill_book_record) .on_conflict_do_nothing() .get_result(&connection) .unwrap(); inserted_bill_book }
注意事项
- 确保用于接收返回结果的
BillBook结构体实现了Queryabletrait,插入用的BillBookAdd结构体实现了Insertabletrait,否则Diesel无法完成结构体和数据库字段的自动映射。 - 由于你使用了
on_conflict_do_nothing()逻辑,当插入触发唯一键冲突时,数据库不会执行插入操作,此时get_result会返回NotFound错误。如果需要冲突时返回已存在的记录,要么替换冲突处理逻辑为on_conflict().do_update(),要么捕获该错误后查询对应冲突记录返回。 - 批量插入场景下,把
get_result替换为get_results即可拿到所有插入成功的记录列表,返回类型为Vec<BillBook>。 - 该能力依赖数据库对
RETURNING语法的支持,你当前使用的PostgreSQL完全兼容,不需要升级Diesel版本或者新增feature配置。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

