Learn Rust Coding · บทเรียน

การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)

เชื่อมต่อบริการเว็บ Rust ของคุณกับฐานข้อมูลโดยใช้ ORM หรือตัวสร้างคำค้นยอดนิยม เช่น SQLx หรือ Diesel

บทเรียน 2 จาก 311 ขั้นตอน

การเชื่อมต่อฐานข้อมูล (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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. REST APIs ด้วย Actix-web/Rocket
  2. การเชื่อมต่อฐานข้อมูล (SQLx/Diesel)
  3. การยืนยันตัวตนและการอนุญาตสิทธิ์
← กลับไปที่ Learn Rust Coding