آن چه در این مقاله خواهید خواند:
مقدمه
jOOQ یا Hibernate، کدام یک را انتخاب کنیم؟ تفاوت این دو با یکدیگر چیست؟ به طور خلاصه میتوان گفت، Hibernate یک رویکرد Java-first دارد، که در آن شما (معمولا) ابتدا کلاسهای جاوا و mapping خود را مینویسید. سپس به database (جدولها) خود فکر میکنید. ولی در jOOQ شما ابتدا با database یا SQL سروکار دارید.
Hibernate، اگر استانداردها برای شما اهمیتی داشته باشند و اگر JCP را نیز در سطح ISO، ANSI، IEEE و غیره قرار دهید، توانسته است به یکی از استانداردهای بالفعل و یا به اصطلاح de-facto در اکوسیستم جاوا و همچنین یک استاندارد implementation واقعی JavaEE تبدیل شود.
هدف ما در این مقاله صحبت راجع به استانداردها نیست، بلکه هدف ما بررسی دیدگاهها است. Hibernate دیدگاه JPA از ORM را به اشتراک میگذارد، ولی در طرف مقابل jOOQ، دیدگاه SQL از یک querying قدرتمند را به اشتراک میگذارد. پس بیایید به خاطر آرگومان (argument)، از jPA، ORM و hibernate به جای یکدیگر، و از SQL، JDBC و jOOQ نیز به جای یکدیگر استفاده کنیم.
jOOQ یا Hibernate، کدام یک را باید انتخاب کرد؟
این روزها این سوال که “چرا هر کسی نباید از Hibernate استفاده کند؟” همیشه به طور مکرر پرسیده میشود؛ پرسش این سوال به این دلیل است که Hibernate یک استاندارد واقعی (de-facto standard) است و همچنین اولین انتخاب فریمورک در بین بسیاری از فریمورک های دیگر مانند Grails (که از GORM استفاده میکند و که خود آن نیز دوباره از Hibernate استفاده میکند) است، ولی باز هم با این حال، حتی گاوین کینگ (Gavin King)، خالق فریمورک Hibernate، اعتقاد دارد که Hibernate نباید برای همه چیز مورد استفاده قرار گیرد.
اگر که این چنین است، آیا نکات کاربردی و کمکیای برای تصمیم گیری عینی وجود دارد که بتوانید با در نظر گرفتن آنها تصمیم بگیرید که چه زمانی از یک ORM و چه زمانی از SQL استفاده کنید؟
بحث در یک سطح بالاتر
ابتدا اجازه دهید بحث انتخاب بین jOOQ یا Hibernate را به یک سطح بالاتر ببریم. بهجای تصمیمگیری در انتخاب بین jOOQ یا Hibernate بهعنوان پیادهسازی مشخص (concrete implementations) دامنههای خودشان، بیایید ابتدا به مقایسهی بین ORM و SQL و موارد مختلف استفاده از آنها بپردازیم.
هنگام تصمیم گیری راجع به انتخاب بین ORM (به عنوان مثال Hibernate) و SQL (به عنوان مثال jOOQ)، سوالی که ابتدا باید از خود بپرسید، راجع به پیچیدگی پروژه نیست. بیشتر توسعهدهندگان و برنامهنویسان از jOOQ در schemaهای متوسط (medium-sized schemas) همراه با هزاران tables/views استفاده میکنند. اغلب، این schemaها به صورت شدیدی نرمالسازی (normalised) میشوند و حتی گاهی در شش RDBMS مختلف مستقر میشوند. jOOQ به طور مخصوص برای کار در این سناریوها طراحی شده و همچنین در عین حال موارد استفاده ساده را نیز در نظر میگیرد.
بنابراین، به جای فکر کردن و سوال پرسیدن راجع به پیچیدگی پروژه، برای انتخاب بین jOOQ یا Hibernate سوالات زیر را از خود بپرسید؟
-
آیا مدل دادهی (data model) شما طراحی اپلیکیشن را هدایت میکند و یا طراحی اپلیکیشن شما مدل(های) داده را هدایت میکند؟
یکی از جنبههای اصلی مورد بحث در اینجا میزان اهمیت شما به پایگاه داده (database) خود است؛ این اهمیت به این معنا است که database ممکن است اپلیکیشن شما را زنده نگه داشته باشد. (اغلب اوقات، اپلیکیشنها میآیند و میروند، آنها ممکن است 5 سال بعد دوباره در پایتون، جاوا اسکریپت و غیره نوشته شوند). و یا اینکه شما دارای چندین برنامه هستید که به یک database دسترسی دارند: اپلیکیشن جاوای شما، برخی از اسکریپتهای Perl، procedureهای ذخیره شده و غیره. اگر به این صورت است، طراحی database در پروژهی شما اولویت دارد و jOOQ میتواند در این setupها بسیار خوب عمل کند.
ولی اگر که لزوماً شما به database خود اهمیت خاصی نمیدهید، به این معنا که فقط میخواهید دامنهی جاوای خود را در جایی persist کنید، و database شما یک database رابطهای (relational database) است، در انتخاب بین jOOQ یا Hibernate، Hibernate ممکن است انتخاب بهتری برای شما باشد (حداقل در مراحل اولیهی پروژهی خود)، زیرا شما به راحتی میتوانید schema Database خود را از مدل Entity خود به وجود آورید.
-
آیا شما به طور معمول پیچیده خواندن (complex reading) و ساده نوشتن (simple writing) انجام میدهید و یا از نوشتن پیچیده (complex writing) استفاده میکنید؟
وقتی که شما از خواندن پیچیده استفاده میکنید، وقتی که از جداول (table) زیاد استفاده میکنید، وقتی دادههای زیادی را در پایگاه داده خود قرار میدهید، وقتی که گزارش میدهید و وقتی که خواندن و نوشتن انبوه انجام میدهید، SQL از همه چیز برای شما مفید تر است. وقتی که شما به داده های خود بر اساس نظریه مجموعهها (set theory) نگاه میکنید، به عنوان مثال، دادهها را به عنوان یک کل در نظر میگیرید، با این وجود، نوشتن CRUD با SQL خسته کننده است. به همین دلیل است که وقتی شما در حال کار کردن بر روی tableهای تکی هستید، jOOQ یک API به سبک ActiveRecord در اختیار شما قرار میدهد که بخشهای خستهکننده را کنترل میکند.
ولی اگر برخلاف حالت بالا نوشتن شما پیچیده باشد، یعنی شما باید یک گراف object پیچیده با 20 entity درگیر را در حافظه بارگذاری کنید، سپس یک قفل optimistic روی آن انجام دهید، آن را به روش های مختلف modify کنید و دوباره آن را در یک حرکت persist کنید، در اینجا SQL/jOOQ به شما کمکی نخواهد کرد و این در اصل همان چیزی است که Hibernate برای آن ایجاد شده است.
سخن آخر
بیشتر افراد اعتقاد دارند که باید باور داشته باشید دادههایتان همیشگی هستند، یعنی شما باید “همیشه” فرض کنید که databaseتان، اپلیکیشن را زنده نگه میدارد؛ چون بازنویسی (بخشهایی از) یک اپلیکیشن بسیار ساده تر از انتقال کل database است. همچنین داشتن یکschema database تمیز و خوب طراحی شده نیز همیشه بعد از اتمام یک پروژه، به ویژه یک پروژهی پیچیده نتایج خوبی را به همراه خواهد داشت.
همچنین، اکثر پروژهها 90٪ خواندن و 10٪ نوشتن را انجام میدهند، نوشتن اغلب پیچیده نیست (2-3 جدول modified شده به همراه یک transaction)؛ به این معنی که در بیشتر مواقع، پیچیدگی توسط Hibernate / JPA حل میشود و دیگر به cachهای سطح دوم نیازی نیست. مردم اغلب این ویژگیها را اشتباه درک میکنند و به راحتی cach را خاموش میکنند، cach Hibernate را همیشه به سرور میریزند و بنابراین به این صورت از Hibernate به روشی اشتباه استفاده میکنند.
با این حال، اگر که هنوز در مورد انتخاب jOOQ یا Hibernate تصمیم نگرفته اید، میتوانید از راه میانی این دو نیز استفاده کنید. به این صورت که از jOOQ فقط برای گزارش، پردازش دسته ای و غیره استفاده کنید و از Hibernate برای انجام CRUD خود.