December 15, 2013

ORM : Mapping On Table

Java Persistence API အကြောင်းကို ရေးသားလာခဲ့သည်မှာ တတိယ အကြိမ်သို့ရောက်ရှိ ခဲ့ပြီဖြစ်သည်။ ပထမဦးဆုံး အကြိမ်မှာတော့ JPA ၏ အခြေခံ သဘောတရားများအား ဖော်ပြခဲ့ပါသည်။ ထို့နောက် ဒုတိယ အကြိမ်အနေနဲ့ JPA ကို Java SE ပတ်ဝင်းကျင်မှာ ရေသားနိုင်ရန် ပတ်ဝင်းကျင်ပြင်ဆင်မှု့ကို အဓိကထား ဖော်ပြခဲ့၏။

လေ့လာစသူများတွင် အဓိက ကြုံတွေ့ရလေ့ရှိသော အခက်အခဲမှာ ပတ်ဝင်းကျင် ပြင်ဆင်မှု့ပင် ဖြစ်၏။ စာအုပ်ဖတ်၍ လွယ်ပါသည်။ သို့ရာတွင် လက်တွေ့ရေးကြည့်သောအခါ ဗားရှင်းမတူရတာနဲ့ တစ်နေနေရာမှာ လွဲနေတတ်တာနဲ့ တော်ရုံနဲ့ ဆက်မလုပ်ဖြစ်သည်က များ၏။

ထို့ကြောင့် ဒုတိယအခေါက်တွင် တဆင့်ချင်း ပုံများကို ကူး၍ ဖော်ပြခဲ့ပါသည်။ မြန်မာပြည်၏ လက်ရှိ ကွန်နက်ရှင်ကြောင့် ဓာတ်ပုံတွေများတောသည့်အခါ မကြာခဏ Error ဖြစ်ခဲ့ရပါသည်။ အပင်ပမ်းခံခဲ့ရသမျှ စာဖတ်သူများအတွက် အထောက်အကူပြုမည်ဆိုပါက ဝမ်းသာရပါမည်။

ယခုတစ်ခေါက်မှ စ၍ JPA ရဲ့ အနှစ်သာရဖြစ်သော ORM အကြောင်းကို ဆက်လက်ရေးသားသွားပါဦးမည်။


Object Relation Mapping ဆိုသည်မှာ


ORM ဆိုသည်မှာ Object Oriented Programming ဘာသာရပ်တွင် အသုံးပြုသော Object များနှင့် Relational Data Model တွင် အသုံးပြုသော Relation များ၏ သဘောသဘာဝမတူညီမှု့များအပေါ်၊ Framework မှတဆင့် ကြားခံ Map လုပ်ပေးခြင်းအားဖြင့်၊ OOP ဘာသာရပ်များဘက်တွင် Relational Database အတွင်းမှအချက်အလက်များအား Object အနေနှင့် အသုံးချနိုင်ရန် စီမံထားသော အတွေးအခေါ်အယူအဆ တစ်ခုဖြစ်ပါသည်။

RDB ၏ Relation ဖြစ်သော Table များနှင့် Map လုပ်ထားသော Object Class များအား Entity ဟု ခေါ်ဆိုပြီး၊ ORM အားအသုံးပြု၍ အောက်ပါအတိုင်း Map လုပ်ပေးနိုင်ပါသည်။

  • Table တစ်ခုချင်းစီနှင့် Entity တစ်ခုချင်းစီအား Map လုပ်ခြင်း
  • Table အချင်းချင်း၏ ပတ်သက်မှု့အား Entity များတွင် Map လုပ်ခြင်း
  • Entity များ၏ OOP Concept များအား Map လုပ်ခြင်း
ဤကဲ့သို့ ORM ၏ Concept များအား အသုံးချထားသော Framework အား အသုံးပြုခြင်းအားဖြင့်၊ Java Developer များသည် Relational Database အတွင်းမှ Data များအား၊ Java Object များအနေနှင့် ကြည့်မြင်၍ အသုံးချနိုင်ပါသည်။

ထို့အပြင် Relational Database Management System ခြင်း မတူညီမှု့ကြောင့်၊ Data Type များမတူညီမှု့များအား၊ ORM Framework မှ ကြားခံကူညီပေးသောကြောင့်၊ တစ်ခါရေးထားသော မိမိ၏ Application များအား၊ မည်သည့် Database Management System များကိုမဆို လွယ်ကူစာ ပြောင်းရွှေ့ အသုံးပြုနိုင်မည် ဖြစ်သည်။


Entity Class


Relational Database အတွင်းရှိ Table တစ်ခုနှင့် Map လုပ်နိုင်သည်မှာ Entity Class ဖြစ်၏။ အောက်ပါပုံကိုကြည့်ပါ။ Student Table နှင့် Java တွင် အသုံးပြုမည့် Class အား Map လုပ်ပါမည်။


Student Class အတွင်းတွင် student Table ၏ Column များနှင့် ထပ်တူ Member Fields များအား ရေးသားထားပါသည်။ လက်တွေ့ Student Entity Class အား ရေးသားကြည့်ပါမည်။
@Entity
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    private int id;
    private String address;
    
    @Temporal(TemporalType.DATE)
    @Column(name="birth_date")
    private Date birthDate;
    private String mail;
    private String name;
    
    @Column(name="nrc_number")
    private String nrcNumber;
    private String ocupation;
    private String phone;    
    
    public Student() {
    }  
    // getter and setter
}
Entity Class များအား POJO အနေနဲ့ ရေးသားနိုင်ပြီး၊ Serializable Interface အား Implements လုပ်ထားရန် လိုအပ်ပါသည်။ Entity Class တို့သည် Java Beans Technology အား အခြေခံထားပါသဖြင့် Java Beans ၏ Naming Rule များအား လိုက်နာ၍ Getter နှင့် Setter များအား ရေးသားရန်လိုအပ်၏။ Entity Class သည် Top Level Class တစ်ခုဖြစ်ရန် လိုအပ်ပြီး final လည်း ဖြစ်၍မရပါ။ ထို့အပြင် Container မှ အသုံးပြုမည် ဖြစ်သောကြောင့် Argument မပါသော Constructor လည်း မရှိမဖြစ်လိုအပ်ပါသည်။

အဆိုပါ အချက်များအား လိုက်နာသော POJO Class တစ်ခုအား Entity အဖြစ်အသုံးပြုလိုသည့်အခါ @Entity ဟု Annotation အား ဖြည့်စွက်ရေးသားလိုက်ပါက Entity Class အဖြစ် အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။

နောက်သတိပြုရန် အချက်တစ်ခုမှာ Entity Class တစ်ခုအတွင်းတွင် @Id ကို ရေးသားထားသော ID Member Field တစ်ခု အနည်းဆုံးလိုအပ်ပါသည်။ Relational Data Model တွင် Table တစ်ခုအတွင်း အဓိပ္ပါယ်တူသော Relation များအား ရေးသား၍ မရနိုင်အောင် စီးကမ်းသတ်မှတ်ထားပါသည်။ အဘယ်ကြောင့်ဆိုသော် Table တစ်ခုအတွင်းရှိ Data တစ်ခုအား ခွဲခြားသိရှိရန် လိုအပ်သောကြောင့် ဖြစ်သည်။ ဤ စီးကမ်းအား စောင့်တည်နိုင်ရန် Relational Database တွင် Primary Key အား အသုံးပြုပါသည်။ ထို့ကြောင့် Entity တွင်လည်း Primary Key Column နှင့် Map လုပ်ရန် ID Member အား အသုံးပြုရခြင်း ဖြစ်ပါသည်။

ပုံမှန်အတိုင်း အသုံးပြုမည်ဆိုပါက Entity Class ၏ အမည်နှင့် တူညီသော Table အား Map လုပ်မည် ဖြစ်ပါသည်။ တဖန် Entity Class ၏ Member Fields များနှင့် အမည်တူ Column များအား Map လုပ်မည် ဖြစ်ကြပါသည်။ ထို့ကြောင့် အထွေအထူး သတ်မှတ်ရန် မလိုအပ်ပါက @Entity နှင့် @ID အား အသုံးပြုရုံဖြင့် Map လုပ်နိုင်မည် ဖြစ်ပါသည်။

သို့သော်လည်း အောက်ပါ အခြေအနေများတွင် သက်ဆိုင်သော Annotation များအား အသုံးပြု၍ သီးခြား Map လုပ်ပေးရန် လိုအပ်ပါသည်။

  • Table Name များနှင့် ခွဲခြား၍ Entity Class များအား အမည်ပေးလိုသည့်အခါ
  • Entity Class တစ်ခုနှင့် Table အများအား Map လုပ်လိုသည့်အခါ
  • Column Name များနှင့် မတူညီသော Member Fields Name များအား အသုံးပြုလိုသောအခါ
  • Collection များ၊ Class များအား Member အဖြစ် အသုံးပြုလိုသည့်အခါ
  • Table တွင် မပါဝင်သော Member Fields များအား အသုံးပြုလိုသောအခါ
  • အစရှိသဖြင့်
Mapping လုပ်ရာတွင် Annotation များအား Fields များ၏ ရှေ့တွင်သော်၎င်း၊ Properties များဖြစ်သော getter method များတွင်သော်၎င်း ရေးသားအသုံးပြုနိုင်ပါသည်။ ထို့အပြင် XML Mapping File များအား အသုံးပြု၍လည်း Map လုပ်နိုင်ပါသော်လည်း ဤနေရာတွင် Annotation အားအသုံးပြု၍ Mapping လုပ်သောနည်းကိုသာ ဖော်ပြသွားမည် ဖြစ်ပါသည်။


Table


Java Persistence API တွင် Table နှင့် Mapping လုပ်နိုင်သော Annotation များမှာ အောက်ပါအတိုင်း ရှိကြ၏။





@Table


အကဲ၍ Table နှင့် ပတ်သက်သော Default တန်ဖိုးများအား ပြောင်းလဲလိုပါက @javax.persistence.Table Annotation အား အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။ ဥပမာအားဖြင့် Entity ၏ အမည်နှင့် မတူညီသော Table တစ်ခုနှင့် Entity အား Mapping လုပ်လိုပါက @Table Annotation အား အသုံးပြုနိုင်ပါသည်။ Book Entity Class အား T_BOOK Table နှင့် Mapping လုပ်လိုသည် ဆိုပါက အောက်ပါအတိုင်း ရေးသားနိုင်ပါသည်။
@Entity
@Table(name="T_BOOK")
public class Book implements Serializable {

    @Id
    @GeneratedValue
    private int id;
    private String title;
    private Float price;
    private String description;
    private String isbn;
    // getter and setter
}

အထက်ပါ Source Code အား အသုံးပြု၍ Run ပြီး Schema အား Create လုပ်၍ ရသော DDL မှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။ Table ၏ အမည်မှာ T_BOOK ဖြစ်၏။ ဤသည်ကို ကြည့်ခြင်းအားဖြင့် @Table အား အသုံးပြုပါက Entity Name နှင့် မတူသော Table နှင့် Map လုပ်နိုင်ကြောင်း သိရှိနိုင်ပါသည်။

CREATE TABLE T_BOOK (
    ID INTEGER NOT NULL, 
    DESCRIPTION VARCHAR(255), 
    ISBN VARCHAR(255), 
    PRICE FLOAT, 
    TITLE VARCHAR(255), 
    PRIMARY KEY (ID)
)


@SecondaryTable


ယခုတိုင် အသုံးပြုခဲ့သော Entity Class များသည် Table တစ်ခုတည်းနှင့်သာ Mapping လုပ်ခဲ့ပြီး၊ အဆိုပါ Table အား Primary Table ဟုခေါ်ဆိုပါသည်။ သို့ရာတွင် တစ်ခါတစ်ရံ လက်ရှိရှိပြီးသား Data Model တစ်ခုအား အခြားသော Table များတွင် ဖြန့်၍ အသုံးပြုလိုသည့်အခါများလည်းရှိမည်။ ထိုအခါမျိုးတွင် @SecondaryTable Annotation အား အသုံးပြုနိုင်မည်ဖြစ်ပါသည်။ အကယ်၍ Secondary Table အများအား အသုံးပြုလိုပါက @SecondaryTables Annotation အား အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။

@Entity
@SecondaryTables(
        value={
                @SecondaryTable(name="COUNTRY"),
                @SecondaryTable(name="CITY")
        }
)
public class Address implements Serializable{

    @Id
    @GeneratedValue
    private int id;
    private String address;
    
    @Column(table="CITY")
    private String city;
    @Column(table="CITY")
    private String state;
    @Column(table="COUNTRY")
    private String country;
    
    // getter, setter and constructor
}

အထက်ပါ ကုဒ်ထဲတွင် Secondary Table အဖြစ်သတ်မှတ်လိုသည့် CITY နှင့် COUNTRY တို့အား @SecondaryTable Annotation အားအသုံးပြု၍ ရေးသားပြီး၊ သက်ဆိုင်ရာ Table နှင့် ပတ်သက်သည့် Column များအား @Column Attribute အား အသုံးပြု၍ ရေးသားပါသည်။ Column Annotation ၏ name Attribute တွင် Mapping လုပ်လိုသည့် Table Name အား ရေးသားရပါမည်။

အထက်ပါ ကုဒ်များဖြင့် Schema အား Generate လုပ်ကြည့်သောအခါ အောက်ပါအတိုင်း DDL ကို ရရှိပါသည်။ အထက်တွင် သတ်မှတ်ထားသော Column အသီးသီးသည် ပတ်သက်ရာ Table အတွင်းတွင် ပါဝင်၍ ဖော်ပြနိုင်သည်ကို တွေ့ရပါသည်။

CREATE TABLE ADDRESS (
    ID INTEGER NOT NULL, 
    ADDRESS VARCHAR(255), 
    PRIMARY KEY (ID)
)
CREATE TABLE COUNTRY (
    ID INTEGER NOT NULL, 
    COUNTRY VARCHAR(255), 
    PRIMARY KEY (ID)
)
CREATE TABLE CITY (
    ID INTEGER NOT NULL, 
    CITY VARCHAR(255), 
    STATE VARCHAR(255), 
    PRIMARY KEY (ID)
)
ALTER TABLE COUNTRY ADD CONSTRAINT 
    FK_COUNTRY_ID FOREIGN KEY (ID) 
    REFERENCES ADDRESS (ID)
ALTER TABLE CITY ADD CONSTRAINT 
    FK_CITY_ID FOREIGN KEY (ID) 
    REFERENCES ADDRESS (ID)

ကျွှန်တော်တို့ ဒီတစ်ခေါက် ORM ၏ အခြေခံသဘောတရား အားလေ့လာခဲ့ပြီး၊ လက်တွေ့ Table နှင့် ပတ်သက်သော Mapping များအား လက်တွေ့ ရေးသားလေ့လာခဲ့၏။ နောက်ဘလောဂ်ဖြင့် Primary Key နှင့် ပတ်သက်သော Mapping လုပ်ပုံလုပ်နည်းအား ဆက်လက် လေ့လာသွားပါဦးမည်။

လေးစားစွာဖြင့်
မင်းလွင်

1 comment:

  1. Sir Min Lwin ! I would like to suggest one thing. Please add feature to comment via FaceBook. I always read and share your posts. Great ! Another . Please don't mind me , I also want to know about Spring .

    ReplyDelete