0Pricing
Learn Rust Coding · 강의

CRUD 연산

쿼리하고 실행하기

CRUD 연산은(는) CoddyKit의 무료 Learn Rust Coding 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Learn Rust Coding 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Learn Rust Coding 강의에는 총 4개의 강의가 포함되어 있습니다.

sqlx를 사용한 CRUD

CRUD는 Create, Read, Update, Delete를 의미합니다. sqlx에서는 이를 두 가지 실행 방식으로 나눕니다:

  • 행을 반환하는 쿼리에는 fetch_*
  • 데이터를 변경하는 문에는 execute

생성(INSERT)

바인딩된 매개변수로 행을 삽입하고 execute를 통해 실행합니다. 생성된 ID를 다시 받으려면 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
}

일반 Rust로 CRUD 모델링하기

메모리 내 맵을 대상으로 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 작업에 대한 이해도를 확인해 보세요.

복습

sqlx를 사용한 CRUD를 배웠습니다:

  • fetch_one, fetch_optional, fetch_all로 행을 읽습니다
  • execute는 데이터를 변경하고 rows_affected()를 보고합니다
  • RETURNING은 생성된 값을 가져옵니다
  • begin/commit/rollback을 사용한 트랜잭션은 원자성을 보장합니다

다음 주제: 스키마를 발전시키는 마이그레이션입니다.

자주 묻는 질문

“CRUD 연산” 강의는 무료인가요?

네 — “CRUD 연산” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Learn Rust Coding 강의 전체를 잠금 해제할 수 있습니다. Learn Rust Coding 강의에는 총 4개의 강의가 포함되어 있습니다.

“CRUD 연산”에서 뭘 배우나요?

쿼리하고 실행하기 브라우저에서 직접 실행하는 실습 코드로 Learn Rust Coding을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Learn Rust Coding을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Learn Rust Coding은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“CRUD 연산” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Learn Rust Coding 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Learn Rust Coding 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 데이터베이스 연결하기
  2. 컴파일 시 검증되는 쿼리
  3. CRUD 연산
  4. 마이그레이션
← Learn Rust Coding(으)로 돌아가기