การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)
เชื่อมต่อบริการเว็บ Rust ของคุณกับฐานข้อมูลโดยใช้ ORM หรือตัวสร้างคำค้นยอดนิยม เช่น SQLx หรือ Diesel
การเชื่อมต่อฐานข้อมูล (SQLx/Diesel) เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน
เหตุใดจึงต้องใช้ฐานข้อมูลสำหรับเว็บ
บริการเว็บมักต้องจัดเก็บและเรียกคืนข้อมูลอย่างถาวร ลองนึกถึงโพรไฟล์ผู้ใช้ แค็ตตาล็อกสินค้า หรือบทความบล็อก ข้อมูลเหล่านี้จำเป็นต้องอยู่ในที่ใดที่หนึ่งนอกเหนือจากหน่วยความจำของโปรแกรม
ฐานข้อมูลมอบวิธีจัดการข้อมูลอย่างเป็นระบบ ช่วยให้ข้อมูลปลอดภัย สอดคล้องกัน และเข้าถึงได้ การเชื่อมต่อบริการเว็บ Rust ของคุณกับฐานข้อมูลจึงเป็นงานหลักสำหรับแอปพลิเคชันในโลกจริงส่วนใหญ่
SQLx: เพื่อนคู่ใจด้านฐานข้อมูลแบบอะซิงโครนัส
ใน Rust เรามีเครื่องมือยอดเยี่ยมสำหรับการโต้ตอบกับฐานข้อมูล ตัวเลือกยอดนิยมสองตัวคือ SQLx และ Diesel
- SQLx: แครต SQL แบบอะซิงโครนัสที่เขียนด้วย Rust ล้วน พร้อมตรวจสอบคำสั่งค้นหาขณะคอมไพล์ มักเป็นตัวเลือกที่ต้องการสำหรับบริการเว็บแบบอะซิงโครนัสที่สร้างด้วยเฟรมเวิร์กอย่าง Tokio
- Diesel: ORM (ตัวจับคู่เชิงวัตถุกับเชิงสัมพันธ์) ที่ทรงพลัง ซึ่งมอบวิธีโต้ตอบกับฐานข้อมูลในระดับนามธรรมมากขึ้น โดยจับคู่สตรักต์ของ Rust กับตารางฐานข้อมูลโดยตรง โดยทั่วไปจะทำงานแบบพร้อมกัน
ในบทเรียนนี้ เราจะเน้น SQLx เนื่องจากรองรับการทำงานแบบอะซิงโครนัสได้ดี ซึ่งสอดคล้องกับการพัฒนาบริการเว็บ Rust สมัยใหม่
การตั้งค่า SQLx: ส่วนอ้างอิง
ก่อนเขียนโค้ด คุณต้องเพิ่ม sqlx และ tokio ลงใน Cargo.toml ของโครงการ tokio จัดเตรียมรันไทม์แบบอะซิงโครนัสที่ sqlx ต้องใช้
ตัวอย่างเช่น หากต้องการใช้ SQLite (ฐานข้อมูลแบบไฟล์ที่ใช้งานง่ายสำหรับการพัฒนาในเครื่อง) ร่วมกับ SQLx ไฟล์ Cargo.toml ของคุณอาจมีลักษณะดังนี้:
[dependencies]
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "sqlite"] }
tokio = { version = "1", features = ["full"] }โดยทั่วไป คุณจะใช้ตัวแปรสภาพแวดล้อม DATABASE_URL เพื่อกำหนดค่าข้อความการเชื่อมต่อฐานข้อมูลด้วย
เชื่อมต่อฐานข้อมูลแรกของคุณ
มาสร้างการเชื่อมต่อกับฐานข้อมูล SQLite ในหน่วยความจำกัน SQLx ใช้กลุ่มการเชื่อมต่อ ซึ่งจัดการการเชื่อมต่อฐานข้อมูลหลายรายการอย่างมีประสิทธิภาพ เพื่อรองรับคำขอที่ทำงานพร้อมกันในบริการเว็บของคุณ
ลองเรียกใช้ตัวอย่างนี้:
use sqlx::SqlitePool;
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
// Use an in-memory SQLite database for simplicity
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
println!("Successfully connected to the database!");
// In a real web app, 'pool' would be passed around or stored in app state.
Ok(())
}จัดโครงสร้างข้อมูลด้วยตาราง
ก่อนจัดเก็บข้อมูล เราต้องกำหนดแบบแผนฐานข้อมูลโดยใช้ DDL (ภาษานิยามข้อมูล) มา สร้างตาราง tasks อย่างง่ายกัน
มาโคร sqlx::query! ช่วยให้คุณฝัง SQL ลงในโค้ด Rust ได้โดยตรง และยังตรวจสอบ SQL ของคุณขณะคอมไพล์ได้ด้วย
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
// Create a 'tasks' table if it doesn't exist
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
println!("Table 'tasks' created successfully!");
Ok(())
}เพิ่มระเบียนใหม่
เมื่อมีตารางแล้ว มาเพิ่มข้อมูลกัน เราจะใช้คำสั่ง INSERT พร้อมการผูกพารามิเตอร์ วิธีนี้ช่วยป้องกันการแทรกคำสั่ง SQL และทำให้คำสั่งค้นหาของคุณปลอดภัยยิ่งขึ้น
สังเกตว่ามีการใช้ตัวแทน ? สำหรับพารามิเตอร์ และส่งค่าไปยัง .bind()
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
// Insert a new task
let description = "Learn SQLx";
let completed = false;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
description,
completed
).execute(&pool).await?;
println!("Task '{}' inserted successfully!", description);
Ok(())
}เรียกดูข้อมูลด้วย SELECT
หากต้องการดึงข้อมูลจากตาราง tasks เราจะใช้คำสั่ง SELECT SQLx มีเมธอดอย่าง .fetch_all() หรือ .fetch_one() สำหรับรับผลลัพธ์
คุณสามารถวนซ้ำผ่านแถวที่ส่งคืนมา และเข้าถึงคอลัมน์ด้วยชื่อหรือดัชนี
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Learn SQLx", false
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Build a web app", false
).execute(&pool).await?;
// Fetch and print all tasks
println!("\n--- All Tasks ---");
let rows = query!("SELECT id, description, completed FROM tasks")
.fetch_all(&pool).await?;
for row in rows {
println!("ID: {}, Desc: {}, Done: {}",
row.id, row.description, row.completed);
}
Ok(())
}ข้อมูลที่ปลอดภัยด้านชนิดข้อมูลด้วยสตรักต์
การดึงข้อมูลจากแถวด้วยตนเองอาจทำให้เกิดข้อผิดพลาดได้ง่าย มาโคร query_as! ของ SQLx เมื่อใช้ร่วมกับ #[derive(FromRow)] ช่วยให้คุณจับคู่ผลลัพธ์จากคำสั่งค้นหาเข้ากับสตรักต์ของ Rust ได้โดยตรง
วิธีนี้มอบความปลอดภัยด้านชนิดข้อมูลที่เข้มงวด และทำให้โค้ดของคุณสะอาดและใช้งานง่ายขึ้นมาก
use sqlx::{FromRow, SqlitePool, query, query_as};
use tokio;
#[derive(Debug, FromRow)]
struct Task {
id: i64,
description: String,
completed: bool,
}
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Learn SQLx", false
).execute(&pool).await?;
// Fetch tasks directly into our Task struct
println!("\n--- Tasks as Structs ---");
let tasks = query_as::<_, Task>("SELECT id, description, completed FROM tasks")
.fetch_all(&pool).await?;
for task in tasks {
println!("{:?}", task);
}
Ok(())
}ปรับปรุงและลบระเบียน
การปรับปรุงและลบข้อมูลมีรูปแบบคล้ายกับการเพิ่มข้อมูล คุณใช้คำสั่ง SQL UPDATE และ DELETE พร้อมการผูกพารามิเตอร์
- UPDATE: เปลี่ยนแถวที่มีอยู่ตามเงื่อนไข
WHERE - DELETE: ลบแถวตามเงื่อนไข
WHERE
โปรดระมัดระวังเงื่อนไข WHERE ใน UPDATE และ DELETE เสมอ เพื่อหลีกเลี่ยงการสูญเสียข้อมูลโดยไม่ตั้งใจ
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Finish lesson", false
).execute(&pool).await?;
let task_id_to_update = 1;
// Update a task
query!(
"UPDATE tasks SET completed = ? WHERE id = ?",
true,
task_id_to_update
).execute(&pool).await?;
println!("Task {} updated.", task_id_to_update);
// Delete a task (uncomment to run, careful with IDs after update)
// let task_id_to_delete = 1;
// query!(
// "DELETE FROM tasks WHERE id = ?",
// task_id_to_delete
// ).execute(&pool).await?;
// println!("Task {} deleted.", task_id_to_delete);
Ok(())
}ทดสอบทักษะฐานข้อมูลของคุณ
ข้อความใดต่อไปนี้เป็น TRUE เกี่ยวกับ SQLx ในบริการเว็บ Rust
การเชื่อมต่อฐานข้อมูล: ประเด็นสำคัญ
คุณได้ก้าวหน้าอย่างสำคัญในการสร้างบริการเว็บ Rust ที่ทนทาน ด้วยการเรียนรู้การเชื่อมต่อฐานข้อมูล
- การคงอยู่ของข้อมูล: ฐานข้อมูลมีความสำคัญต่อการจัดเก็บข้อมูลแอปพลิเคชัน
- SQLx: แครต SQL แบบอะซิงโครนัสที่ตรวจสอบขณะคอมไพล์ เหมาะอย่างยิ่งกับบริการเว็บ
- กลุ่มการเชื่อมต่อ: จำเป็นสำหรับการเข้าถึงฐานข้อมูลอย่างมีประสิทธิภาพและพร้อมกัน
- CRUD: เราได้ครอบคลุมการสร้าง (
INSERT) การเรียกดู (SELECT) การปรับปรุง (UPDATE) และการลบ (DELETE) ข้อมูล - ความปลอดภัยด้านชนิดข้อมูล:
query_as!และ#[derive(FromRow)]ช่วยให้จับคู่ข้อมูลได้อย่างปลอดภัยและสะดวก
ถัดไป คุณสามารถสำรวจการนำการดำเนินการกับฐานข้อมูลเหล่านี้ไปผสานรวมกับเส้นทางเว็บจริงได้
เรียนรู้ Rust ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 39
- บทเรียน
- 144
คำถามที่พบบ่อย
บทเรียน “การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)”
เชื่อมต่อบริการเว็บ Rust ของคุณกับฐานข้อมูลโดยใช้ ORM หรือตัวสร้างคำค้นยอดนิยม เช่น SQLx หรือ Diesel คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน
บทเรียน “การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- REST APIs ด้วย Actix-web/Rocket
- การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)
- การยืนยันตัวตนและการอนุญาตสิทธิ์