การดำเนินการ CRUD
ค้นหาและดำเนินการ
การดำเนินการ CRUD เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
CRUD ด้วย sqlx
CRUD หมายถึง Create, Read, Update และ Delete sqlx แบ่งการทำงานเหล่านี้ออกเป็นรูปแบบการดำเนินการสองแบบ:
fetch_*สำหรับคำสั่งค้นหาที่ส่งคืนแถวexecuteสำหรับคำสั่งที่เปลี่ยนแปลงข้อมูล
การสร้าง (INSERT)
แทรกแถวด้วยพารามิเตอร์ที่ผูกไว้ แล้วเรียกใช้ผ่าน execute ใช้ RETURNING เพื่อรับรหัสที่สร้างขึ้นกลับมา
use sqlx::{Pool, Postgres};
async fn create(pool: &Pool<Postgres>, name: &str) -> i32 {
let rec = sqlx::query!(
"INSERT INTO users (name) VALUES ($1) RETURNING id",
name
).fetch_one(pool).await.unwrap();
rec.id
}การอ่านหนึ่งแถว
fetch_one ต้องได้รับแถวมาเพียงหนึ่งแถวพอดี มิฉะนั้นจะเกิดข้อผิดพลาด ใช้ fetch_optional เมื่อแถวนั้นอาจไม่มีอยู่
use sqlx::{Pool, Postgres};
async fn find(pool: &Pool<Postgres>, id: i32) -> Option<String> {
let rec = sqlx::query!("SELECT name FROM users WHERE id = $1", id)
.fetch_optional(pool)
.await
.unwrap();
rec.map(|r| r.name)
}การอ่านหลายแถว
fetch_all จะส่งคืน Vec ที่มีแถวทั้งหมดซึ่งตรงตามเงื่อนไข
use sqlx::{Pool, Postgres};
async fn all_names(pool: &Pool<Postgres>) -> Vec<String> {
let rows = sqlx::query!("SELECT name FROM users ORDER BY id")
.fetch_all(pool)
.await
.unwrap();
rows.into_iter().map(|r| r.name).collect()
}การปรับปรุงข้อมูล
คำสั่ง UPDATE ใช้ execute ซึ่งส่งคืนผลลัพธ์ที่มีจำนวนแถวที่ได้รับผลกระทบ
use sqlx::{Pool, Postgres};
async fn rename(pool: &Pool<Postgres>, id: i32, name: &str) -> u64 {
let res = sqlx::query!("UPDATE users SET name = $1 WHERE id = $2", name, id)
.execute(pool)
.await
.unwrap();
res.rows_affected()
}การลบข้อมูล
DELETE ก็ใช้ execute เช่นกัน ตรวจสอบ rows_affected() เพื่อดูว่ามีสิ่งใดถูกลบหรือไม่
use sqlx::{Pool, Postgres};
async fn delete(pool: &Pool<Postgres>, id: i32) -> bool {
let res = sqlx::query!("DELETE FROM users WHERE id = $1", id)
.execute(pool)
.await
.unwrap();
res.rows_affected() > 0
}การจำลอง CRUD ด้วย Rust พื้นฐาน
CRUD กับแมปในหน่วยความจำสะท้อนการดำเนินการแบบเดียวกับที่ sqlx ทำกับตาราง
use std::collections::HashMap;
fn main() {
let mut users: HashMap<i32, String> = HashMap::new();
users.insert(1, "Alice".to_string()); // create
println!("{:?}", users.get(&1)); // read
users.insert(1, "Alicia".to_string()); // update
println!("{:?}", users.get(&1));
users.remove(&1); // delete
println!("{:?}", users.get(&1));
}ธุรกรรม
จัดกลุ่มคำสั่งหลายรายการให้ทำงานเป็นอะตอมิกด้วยธุรกรรม ทุกคำสั่งจะสำเร็จพร้อมกันเมื่อเรียก commit หรือไม่มีคำสั่งใดถูกนำไปใช้เลย
use sqlx::{Pool, Postgres};
async fn transfer(pool: &Pool<Postgres>) {
let mut tx = pool.begin().await.unwrap();
sqlx::query!("UPDATE acct SET bal = bal - 10 WHERE id = 1")
.execute(&mut *tx).await.unwrap();
sqlx::query!("UPDATE acct SET bal = bal + 10 WHERE id = 2")
.execute(&mut *tx).await.unwrap();
tx.commit().await.unwrap();
}การย้อนกลับ
หากตัวป้องกันธุรกรรมถูกทิ้งโดยไม่ได้เรียก commit sqlx จะย้อนกลับโดยอัตโนมัติ คุณยังสามารถเรียก rollback ได้โดยตรง
use sqlx::{Pool, Postgres};
async fn maybe(pool: &Pool<Postgres>, ok: bool) {
let mut tx = pool.begin().await.unwrap();
sqlx::query!("INSERT INTO log (msg) VALUES ('x')").execute(&mut *tx).await.unwrap();
if ok { tx.commit().await.unwrap(); } else { tx.rollback().await.unwrap(); }
}การอ่านข้อมูลจำนวนมากแบบสตรีม
สำหรับชุดผลลัพธ์ขนาดใหญ่มาก fetch จะส่งคืนสตรีม เพื่อให้คุณประมวลผลแถวต่าง ๆ ได้โดยไม่ต้องโหลดทั้งหมดไว้ในหน่วยความจำ
use sqlx::{Pool, Postgres};
use futures::TryStreamExt;
async fn stream(pool: &Pool<Postgres>) {
let mut rows = sqlx::query!("SELECT id FROM big_table").fetch(pool);
while let Some(row) = rows.try_next().await.unwrap() {
println!("id {}", row.id);
}
}การจัดการข้อผิดพลาด
การเรียกฐานข้อมูลจะส่งคืน Result ส่งต่อข้อผิดพลาดด้วย ? ในฟังก์ชันที่ส่งคืน Result<_, sqlx::Error> แทนการแกะค่าโดยไม่ตรวจสอบ
use sqlx::{Pool, Postgres};
async fn count(pool: &Pool<Postgres>) -> Result<i64, sqlx::Error> {
let rec = sqlx::query!("SELECT COUNT(*) as n FROM users")
.fetch_one(pool)
.await?;
Ok(rec.n.unwrap_or(0))
}ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับการดำเนินการ CRUD
สรุปทบทวน
คุณได้เรียนรู้ CRUD ด้วย sqlx:
fetch_one,fetch_optional,fetch_allใช้อ่านแถวexecuteเปลี่ยนแปลงข้อมูลและรายงานrows_affected()RETURNINGใช้ดึงค่าที่สร้างขึ้นกลับมา- ธุรกรรมที่ใช้
begin/commit/rollbackช่วยให้การทำงานเป็นอะตอมิก
ถัดไป: การย้ายโครงสร้างเพื่อพัฒนาโครงสร้างฐานข้อมูล
คำถามที่พบบ่อย
บทเรียน “การดำเนินการ CRUD” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การดำเนินการ CRUD” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การดำเนินการ CRUD”
ค้นหาและดำเนินการ คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การดำเนินการ CRUD” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ