0Pricing
Kotlin Academy · درس

إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات

اتصل بقاعدة بيانات واضبط Exposed ونفّذ الشيفرة داخل المعاملات.

إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

ما هو Exposed؟

Exposed هو إطار SQL خفيف من JetBrains مخصّص لـ Kotlin. يوفّر مستويين: Query DSL (تعبيرات SQL آمنة الأنواع) وDAO layer (كيانات بأسلوب Active Record). ويعمل كلاهما داخل معاملات صريحة.

إضافة تبعيات Exposed

أضف التبعية الأساسية، ووصلة مشغّل JDBC، ومشغّل قاعدة البيانات الذي تستخدمه:

dependencies {
    implementation("org.jetbrains.exposed:exposed-core:0.52.0")
    implementation("org.jetbrains.exposed:exposed-jdbc:0.52.0")
    implementation("org.jetbrains.exposed:exposed-dao:0.52.0")
    implementation("com.h2database:h2:2.2.224") // or postgresql driver
    implementation("com.zaxxer:HikariCP:5.1.0")  // connection pooling
}

الاتصال بقاعدة البيانات

استدعِ Database.connect() مرة واحدة عند بدء التشغيل. في بيئة الإنتاج، مرّر HikariDataSource؛ أما في الاختبارات، فيكفي استخدام عنوان JDBC بسيط:

import org.jetbrains.exposed.sql.Database

// Simple (dev/test)
Database.connect(
    url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
    driver = "org.h2.Driver"
)

// Production with HikariCP
Database.connect(HikariDataSource(HikariConfig().apply {
    jdbcUrl = "jdbc:postgresql://localhost/mydb"
    username = "user"
    password = "pass"
    maximumPoolSize = 10
}))

كتلة transaction { }

يجب تشغيل جميع عمليات Exposed داخل كتلة transaction { }. تُجري Exposed عملية الالتزام عند النجاح، وتلغي المعاملة عند وقوع أي استثناء غير مُعالج:

transaction {
    // all DB operations here
    SchemaUtils.create(Users)
}

معاملات ملائمة لـ Coroutine

استخدم newSuspendedTransaction { } من exposed-r2dbc أو exposed-spring-boot-starter للحصول على معاملات متوافقة مع Coroutine. في Ktor، غلّف استدعاءات Exposed الحاجبة داخل withContext(Dispatchers.IO) { transaction { ... } }:

suspend fun findUser(id: Long): User? = withContext(Dispatchers.IO) {
    transaction {
        UserEntity.findById(id)?.toUser()
    }
}

SchemaUtils: إنشاء الجداول وحذفها

استخدم SchemaUtils.create(Table1, Table2) لإنشاء الجداول إذا لم تكن موجودة، واستخدم SchemaUtils.drop() لحذفها. استدعِ ذلك داخل transaction { } عند بدء تشغيل التطبيق:

transaction {
    SchemaUtils.create(Users, Posts, Comments)
}

إعداد اتصال في Ktor

هيّئ قاعدة البيانات داخل وحدة Application لكي يُنفَّذ ذلك مرة واحدة عند بدء تشغيل الخادم:

fun Application.configureDatabase() {
    val dbUrl = environment.config.property("ktor.database.url").getString()
    Database.connect(dbUrl, driver = "org.postgresql.Driver",
        user = "...", password = "...")
    transaction { SchemaUtils.create(Users) }
}

مستويات عزل المعاملات

مرّر مستوى عزل إلى transaction() عندما تحتاج إلى ضمانات اتساق أقوى أو أضعف:

transaction(Connection.TRANSACTION_SERIALIZABLE) {
    // serializable isolation
}

المعاملات المتداخلة

افتراضيًا، تنضم استدعاءات transaction { } المتداخلة إلى المعاملة الخارجية. للحصول على معاملة مستقلة، استخدم transaction(db, outerTransactionIsEmpty = false) { } أو نقطة حفظ.

تسجيل SQL

فعّل تسجيل SQL لرؤية الاستعلامات المُنشأة أثناء التطوير. اضبط StdOutSqlLogger أو مسجّلًا مخصصًا داخل كتلة المعاملة:

transaction {
    addLogger(StdOutSqlLogger)
    // ...
}

أفضل ممارسات تجميع الاتصالات

استخدم دائمًا HikariCP (أو ما يشابهه) في بيئة الإنتاج. اضبط maximumPoolSize ليتوافق مع عدد خيوط التنفيذ في الخادم، واضبط connectionTimeout للفشل سريعًا عند استنفاد التجمع. راقب استخدام التجمع في بيئة الإنتاج.

تحقق سريع

ماذا يحدث إذا وقع استثناء غير مُعالج داخل كتلة transaction { } في Exposed؟

مراجعة: إعداد Exposed وTransaction DSL

أهم النقاط:

  • اتصل بقاعدة البيانات باستخدام Database.connect() مرة واحدة عند بدء التشغيل (واستخدم HikariCP في بيئة الإنتاج)
  • تُنفَّذ جميع عمليات قاعدة البيانات داخل transaction { } — تُجرى عملية الالتزام عند النجاح وتُلغى المعاملة عند وقوع استثناء
  • أنشئ الجداول أو احذفها باستخدام SchemaUtils.create() داخل معاملة
  • غلّف استدعاءات Exposed الحاجبة داخل withContext(Dispatchers.IO) في سياقات Coroutine
  • فعّل StdOutSqlLogger أثناء التطوير لفحص SQL المُنشأ

الأسئلة الشائعة

هل درس «إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات» مجاني؟

نعم — نص درس «إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

ماذا ستتعلم في «إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات»؟

اتصل بقاعدة بيانات واضبط Exposed ونفّذ الشيفرة داخل المعاملات. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟

لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟

نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إعداد Exposed: اتصال قاعدة البيانات وDSL للمعاملات
  2. تعريف الجداول باستخدام Table DSL
  3. عمليات CRUD باستخدام Query DSL: ‏insert وselect وupdate وdelete
  4. Exposed DAO: أصناف Entity والعلاقات
← العودة إلى Kotlin Academy