3. Message.hbm.xml
حال زمان آن رسیده است تا کلاس Message را به جدول message نگاشت کنیم . برای این کار باید یک فایل XML و با نام همان کلاس Entity ایجاد کنیم نام این فایل متشکل از نام کلاس Message به همراه کلمه .hbm و با پسوند Xml می باشد . این فایل باید در همان مسیری باشد که فایل Message.class قرار دارد . در این فایل موارد زیر مشخص میشود :
1. نام کلاس و جدول متناظر با آن .
2. نام Property های کلاس و ستون متناظر با آن در جدول .
3. نوع داده ای هر مقدار
4. نام فیلدی که در جدول به عنوان ID (Pk) تعریف شده است . و همچنین نحوه ایجاد آن .
5. تعریف روابط مانند
• Composition
• Association
• Inheritance
ساختار فایل .hbm مربوط به کلاس Message در زیر آورده شده است :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="Message"
table="MESSAGES">
<id
name="id"
column="MESSAGE_ID">
<generator class="increment"/>
</id>
<property
name="text"
column="MESSAGE_TEXT"/>
<many-to-one
name="nextMessage"
cascade="all"
column="NEXT_MESSAGE_ID"/>
</class>
</hibernate-mapping>
این فایل مشخص می کند که Object های از کلاس Message باید در جدولی به نام MESSAGES ذخیره شوند همچنین متغیر id از کلاس Message باید به جای ستون MESSAGE_ID ، متغیر text در ستون MESSAGE_TEXT وارد شود و فیلد nextMessage که با ستون NEXT_MESSAGE_ID در ارتباط است برای ایجاد یک ارتباط یک به چند مورد استفاده قرار میگیرد .
Hibernate از طریق این فایل تمام دستورات SQL لازم برای عملیات CRUD را ایجاد میکند .
حال فرض کنید که میخواهیم یک message را از دیتا بیس خوانده ، یک message جدید ایجاد کرده و message جدید را به عنوان nextMessage در message اولی وارد کنیم . کدهای زیر این کار را انجام میدهند :
1: Session session = getSessionFactory().openSession();
2: Transaction tx = session.beginTransaction();
// 1 is the generated id of the first message
3: Message message =
(Message) session.load( Message.class, new Long(1) );
4: message.setText("Greetings Earthling");
5: Message nextMessage =
new Message("Take me to your leader please)");
6: message.setNextMessage( nextMessage );
7: tx.commit();
8: session.close();
تکه کد بالا منجر به اجرای دستورات SQL زیر می شود :
select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
where m.MESSAGE_ID = 1
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (2, 'Take me to your leader (please)', null)
update MESSAGES
set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2
where MESSAGE_ID = 1
Hibernate به طور خودکار هر گونه تغییری که ما در message می دهیم را دریافت و آنرا به دیتا بیس منتقل میکند . به این ویژگی Automatic dirty checking گفته می شود . به کمک این ویژگی دیگر لازم نیست که بعد از هرگونه تغییر در یک Persistance class ، بلافاصله Update را صدا بزنیم . مانند آنچه که در کد بالا در خطوط 4 و 6 دیده میشود .
ویژگی دیگری که Hibernate دارد ویژگی Cascading save میباشد . به کمک این ویژگی نیازی به فراخوانی متد Save() از Hibernate برای ذخیره Message جدید نیست . همانطور که در خط 5 مشاهده میکنید message جدید به طور خودکار در دیتابیس ایجاد میشود و دیگر نیازی به فراخوانی متد save() بعد از آن نیست.
نکته دیگری که باید به آن توجه داشت ترتیب اجرای دستورات SQL میباشد . این ترتیب هیچ ارتباطی به ترتیب اجرای کدهای Hibernate ندارد و خود Hibernate از الگوریتمهای پیشرفته ای برای اجرای مناسب دستورات SQL به کار میبرد تا مشکلی در ذخیره سازی و بروز رسانی اطلاعات مانند (foreign key constraint
violations)در دیتابیس ایجاد نشود .