عمليات CRUD
الاستعلام والتنفيذ
عمليات CRUD درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.
ماذا ستتعلم في «عمليات CRUD»؟
الاستعلام والتنفيذ تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟
لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «عمليات CRUD»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟
نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.