Entity Relationship in Java | روابط موجودیتها در جاوا
توضیحات جلسه
جزوه و مستندات
مفاهیم کلیدی
- Entity Relationship
مدیریت و پیادهسازی روابط بین جدولهای دیتابیس در محیط شیگرا، با استفاده از استانداردهای JPA.
- One-to-One (
@OneToOne)
رابطهای که در آن هر نمونه از یک Entity دقیقاً با یک نمونه از Entity دیگر در ارتباط است؛ مانند رابطه بین یک فرد و آدرس منحصربهفرد او.
- One-to-Many (
@OneToMany)
رابطهای که در آن یک موجودیت میتواند با چندین نمونه از موجودیت دیگر در ارتباط باشد؛ مانند دانشجویی که چندین آدرس مختلف دارد.
- Many-to-One (
@ManyToOne)
عکس رابطه یکبهچند است. در این رابطه، چندین نمونه از یک موجودیت به یک نمونه واحد از موجودیت دیگر اشاره میکنند.
معمولاً این سمت، مالک رابطه یا Owner در دیتابیس شناخته میشود و Foreign Key در جدول مربوط به آن قرار میگیرد.
- Many-to-Many (
@ManyToMany)
رابطهای که در آن چندین نمونه از یک موجودیت با چندین نمونه از موجودیت دیگر در ارتباط هستند؛ مانند رابطه بین دانشجویان و درسها، که هر دانشجو چند درس دارد و هر درس نیز میتواند چندین دانشجو داشته باشد.
- Unidirectional
رابطه یکطرفه است. در این نوع رابطه، فقط یکی از کلاسها از وجود کلاس دیگر و رابطه بین آنها اطلاع دارد و فیلد مربوط به آن را در خود نگه میدارد.
- Bidirectional
رابطه دوطرفه است. در این نوع رابطه، هر دو کلاس به یکدیگر ارجاع دارند و میتوان از هر دو سمت به دادههای طرف مقابل دسترسی پیدا کرد.
- Junction Table جدول میانی
جدول کمکیای است که توسط JPA یا Hibernate برای مدیریت روابط ایجاد میشود؛ بهویژه در رابطههای ManyToMany یا رابطههای OneToMany یکطرفه.
این جدول، Foreign Keyهای مربوط به دو سمت رابطه را در خود ذخیره میکند.
موارد مصاحبه ای
- چرا در رابطه
@OneToManyیکطرفه،Hibernateبه صورت خودکار یک جدول میانی یاJunction Tableمیسازد؟
زیرا بدون جدول میانی، برای ذخیره چندین شناسه یا ID در سمت One، یا باید دادهها تکرار شوند که به آن Redundancy گفته میشود و میتواند باعث نقض قوانین Primary Key شود، یا باید از ساختارهای غیراستاندارد مانند نگهداری لیست در یک ستون استفاده کرد.
جدول میانی، تمیزترین راه برای حفظ یکپارچگی دادهها در حالت یکطرفه است.
- تفاوت اصلی
@OneToManyو@ManyToOneدر پیادهسازی دیتابیس چیست؟
در رابطه @ManyToOne، معمولاً ستون Foreign Key مستقیماً در جدول سمت Many ایجاد میشود.
اما در رابطه @OneToMany، اگر این رابطه بهتنهایی استفاده شود، معمولاً یک جدول میانی ایجاد میشود؛ مگر اینکه رابطه با @JoinColumn مدیریت شود.
- چگونه میتوان از ایجاد دو جدول میانی در رابطه
@ManyToManyدوطرفه جلوگیری کرد؟
باید از ویژگی mappedBy در یکی از سمتها استفاده کرد؛ معمولاً در سمتی که مالک رابطه نیست.
با این کار، JPA متوجه میشود که رابطه قبلاً در سمت دیگر تعریف شده است و هر دو سمت باید از یک جدول میانی مشترک استفاده کنند.
- استفاده از
Setبه جایListدر روابط@ManyToManyچه مزیتی دارد؟
استفاده از Set باعث میشود از ذخیره دادههای تکراری در رابطه جلوگیری شود.
همچنین از نظر منطقی، Set با مفهوم مجموعهها در پایگاه داده سازگارتر است.
سناریو کاربردی
در یک سیستم مدیریت دانشگاهی، ابتدا فرض میشود هر Student فقط یک Address دارد. این رابطه از نوع OneToOne است.
در این حالت، JPA یک ستون address_id به جدول دانشجو اضافه میکند.
اما اگر نیازمندی کسبوکار تغییر کند و هر دانشجو بتواند چندین آدرس، مانند آدرس منزل یا محل کار داشته باشد، رابطه به One-to-Many تغییر مییابد.
در این حالت، اگر صرفاً از @OneToMany در کلاس دانشجو استفاده کنیم، Hibernate یک جدول میانی با نام student_address میسازد تا شناسههای هر دو موجودیت را کنار هم قرار دهد.
برای بهینهسازی و حذف این جدول اضافی، بهتر است رابطه به صورت Many-to-One در کلاس آدرس تعریف شود تا هر رکورد آدرس، مستقیماً به شناسه دانشجوی خود اشاره کند.
بیشتر بدانید
- IDE Tip
در محیط IntelliJ IDEA، زمانی که از انوتیشنهای روابط استفاده میکنید، آیکونهای کوچکی در کنار شماره خطوط یا Gutter ظاهر میشوند.
با کلیک روی این آیکونها، میتوانید مستقیماً به کلاس مرتبط منتقل شوید.
- نکته در مورد پکیجها
انوتیشنهای مربوط به روابط، مانند @OneToOne و @ManyToOne، همگی باید از پکیج جدید jakarta.persistence ایمپورت شوند.
- مدیریت جدول میانی
در روابط چندبهچند، اگر نامهای پیشفرض جدول میانی یا ستونهای آن را نمیپسندید، میتوانید از انوتیشن @JoinTable استفاده کنید.
با @JoinTable میتوان نام جدول میانی و ستونهای لینکدهنده را شخصیسازی کرد.
