July 14, 2014

Data Access Object

ပြီးခဲ့တဲ့ရက်တွေတုန်းက အလုပ်ရှုပ်နေတာနဲ့ ဘလောဂ်ကို မရေးဖြစ်ခဲ့ဘူး။ ဒီနေ့တော့ နည်းနည်းအားတာနဲ့ ပြီးခဲ့တဲ့တစ်ခေါက်ရေးခဲ့တဲ့ အပလီကို ဆက်ရေးပါမယ်။ ပြီးခဲ့တဲ့တစ်ခေါက်တုန်းကတော့ Entity တွေကို Table ကနေ Generate လုပ်ခဲ့ပါပြီ။ ယခုတစ်ခေါက်မှာတော့ အဲ့ဒီ Entity တွေကို Access လုပ်တဲ့ Object ကို ရေးပါမယ်။ ဘယ် Entity တွေမဆို အခြေခံအားဖြင့် CRUD တော့လုပ်ရပါမယ်။ အဲ့ဒီ အလုပ်တွေကို လုပ်တဲ့အခါမှာ အသုံးပြုမယ့် Entity ကသာကွာသွားပါမယ်၊ လုပ်ရမှာကတော့ အတူတူဖြစ်ပါလိမ့်မယ်။ အဲ့ဒီအတွက် Generics ကိုသုံးပြီး ရေးကြည့်ပါမယ်။

Genericsဆိုတာက Objectအတွင်းမှာအသုံးပြုမယ့် Object ရဲ့ Typeကို Parameter နဲ့ရယူနိုင်ပြီး၊ အသုံးပြုမယ့် Element တွေကို Abstraction ဖြစ်အောင် လုပ်နိုင်ပါတယ်။ အဲ့ဒီအတွက် Entity ကို Abstraction လုပ်ပြီး Entity တစ်ခုချင်းစီရဲ့ Data Access Object ကို မရေးတော့ပဲ Object တစ်ခုတည်းကနေ Entity အားလုံးကို Access လုပ်လို့ရမယ့် Object မျိုးကို ရေးသားပါမယ်။


Entity Manager


နောက်ပြီးကျွှန်တော်တို့လက်ရှိသုံးနေတဲ့ပတ်ဝင်းကျင်ကတော့ Java EE 7 ရဲ့ Glassfish 4ဖြစ်ပါတယ်။ အဲ့ဒီထဲမှာ EJB ကို သုံးလို့ရပေမယ့် မသုံးထားပါဘူး။ မလိုအပ်တဲ့အတွက်ပါ။ အဲ့ဒီအစား Transaction တွေကို ထိမ်းဖို့အတွက်ကတော့ CDI ကို အသုံးပြုပါမယ်။ အဲ့ဒီတော့ Data Access အတွက် အသုံးပြုမယ့် EntityManager ကိုတော့ CDI ရဲ့ Application Scope မှာ Produce လုပ်ပြီး၊ အဲ့ဒီ EntityManager ကိုပဲ လိုအပ်တဲ့နေရာမှာ Inject လုပ်ပြီးသုံးပါမယ်။ Dao ထဲကနေ လိုအပ်တဲ့အခါမှာ EntityManager ကို Inject လုပ်ပြီးသုံးသွားပါမယ်။

ကျွှန်တော်တို့ ဒီနမှုနာအတွက် CDI ကို အသုံးပြုမှာဖြစ်ပါတယ်။ ScopeBeans တွေ Named တွေဆိုရင်တော့ beans.xml ကို မရေးရင်လည်းရပါတယ်။ ဒါပေမယ့် Dao ကို Default Injection အနေနဲ့ အသုံးပြုမှာဖြစ်တဲ့အတွက် ဒီနေရာမှာတော့ beans.xml ကို အသုံးပြုမှာဖြစ်ပါတယ်။ beans.xml ကို မကြာမကြာရေးရမှာဖြစ်တဲ့အတွက် ecipse ရဲ့ xml template ထဲမှာ သွားပြီး ရေးထားရင် template ထဲက ဖိုင်ကို create လုပ်ပြီးသုံးနိုင်မှာဖြစ်ပါတယ်။
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
 http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
 version="1.1" bean-discovery-mode="all">
</beans>

အထက်ပါအတိုင်း beans.xml ကို ရေးပြီးတဲ့အခါမှာ EntityManager ကို Produce လုပ်မယ့် Bean ကို ရေးရပါမယ်။ EntityManager ကို Application တစ်ခုလုံးမှာ တစ်ခုတည်းအသုံးပြုချင်တဲ့အတွက် ၎င်းကို ApplicationScope ထဲမှာ ရေးပါမယ်။အသုံးပြုလိုတဲ့ EntityManager ကို @PersistanceContext ကို ရေးပြီး Inject လုပ်ပါမယ်။ နောက်ဆုံးgetter method မှာ @Produce ကို အသုံးပြုပြီး အောက်ပါအတိုင်း ရေးသားထားပါတယ်။
@ApplicationScoped
public class CommonProducer {

 @PersistenceContext
 private EntityManager em;
 
 @Produces
 public EntityManager getEm() {
  return em;
 }
}

ဒါဆိုရင် ဒီအပလီကေးရှင်းထဲမှာ EntityManager ကို လိုအပ်တဲ့နေရာမှာ Inject လုပ်ပြီး အသုံးပြုနိုင်မှာဖြစ်တယ်။


Data Access Object


ဆက်လက်ပြီး Data Access Object ကို စဉ်းစားပါမယ်။ အခြေခံအားဖြင့် Dao မှာ Create လုပ်မယ်၊ Reference လုပ်မယ်၊ Update လုပ်မယ်ဗျာ၊ ပြီးရင် Delete လုပ်ပါမယ်။ နောက်ပြီး Reference လုပ်တဲ့နေရာမှာလည်း အားလုံးကို Reference လုပ်တာနဲ့ ID နဲ့ Reference လုပ်တာရှိပါမယ်။ အဲ့ဒီအတွက် Generics Type Interface ကို ရေးပါမယ်။
public interface Dao<T> {
 
 public T persist(T t);
 public List<T> findAll(Class<T> clz);
 public T findById(Object id, Class<T> clz);
 public T update(T t);
 public void delete(T t);

}
အထက်ပါ Dao<T> Interface ဟာ Generic Type Interface ဖြစ်ပါတယ်။ အဲ့ဒီအထဲမှာပါတဲ့ T ဟာ Type Parameter ဖြစ်ပါတယ်။ အဲ့ဒီ T နေရာမှာ အသုံးလိုတဲ့ Type ကို ဖြည့်စွက်ပြီး၊ ၎င်း အတွင်းမှာရှိတဲ့ T နေရာမှာ ၎င်း Type အား အစားထိုး၍ အသုံးပြုသွားမှာဖြစ်တယ်။ အထဲမှာတော့ Create လုပ်ဖို့အတွက် persist method ကို၎င်း၊ အားလုံးကို ရှာဖို့အတွက် findAll method ကို၎င်း၊ id နဲ့ ရှာဖို့အတွက် findById အား၎င်း၊ update လုပ်ဖို့အတွက် update method အား၎င်း၊ delete လုပ်ဖို့အတွက် delete method ကို၎င်း ရေးသားထားပါတယ်။ ဒါဆိုရင် Entity အားလုံးအတွက် အခြေခံ CRUD ကို ဒီ Interface ကို Implement လုပ်ရေးထားတဲ့ Class တစ်ခုတည်းနဲ့ အစဉ်ပြေစွာအသုံးပြုနိုင်မှာဖြစ်ပါတယ်။ နောက်ပိုင်းကျမှ Where တို့ Join တို့ကို အစဉ်ပြေအောင် ရေးနိုင်ဖို့စဉ်းစားပြီးရေးထားပါမယ်။

ဆက်လက်ပြီး ၎င်းကို Implement လုပ်မယ့် DaoImp Class ကို ဆက်ရေးပါမယ်။
public class DaoImp<T> implements Dao<T> {

 @Inject
 private EntityManager em;

 @Override
 @Transactional
 public T persist(T t) {
  em.persist(t);
  return t;
 }

 @Override
 public List<T> findAll(Class<T> clz) {
  return em.createQuery(
    String.format("select a from %s a", clz.getSimpleName()), clz)
    .getResultList();
 }

 @Override
 public T findById(Object id, Class<T> clz) {
  return em.find(clz, id);
 }

 @Override
 @Transactional
 public T update(T t) {
  return em.merge(t);
 }

 @Override
 @Transactional
 public void delete(T t) {
  em.remove(t);
 }

}

ဤ DaoImp သည် Dao အား Implement လုပ်ထားသော Generics Class ဖြစ်သည်။ ၎င်းအထဲတွင်EntityManager object အား အသုံးပြုရန်လိုအပ်ပါသည်။ ထို့ကြောင့် EntityManager သည် DaoImp ၏ Dependency ဖြစ်ပါသည်။ အကြောင်းမှာ DaoImp အားအလုပ်လုပ်စေရန် EntityManager အား မှီခိုနေရသောကြောင့်ဖြစ်သည်။

ဤနေရာတွင် EntityManager အား CDI ၏ Dependency Injection အား အသုံးပြု၍ Inject လုပ်ထားပါသည်။ သို့မဟုတ်ပါက တိုက်ရိုက် DaoImp အထဲတွင် Instanciate လုပ်ရန်၊ ဒါမှမဟုတ် Constructor ဖြင့် ထည့်သွင်းရန်၊ ဒါမှမဟုတ် setter method အား အသုံးပြုရန် လိုအပ်ပါလိမ့်မယ်။ ဤနေရာတွင် Dependency Injection အားအသုံးပြု၍ ၎င်းတို့အကြားရှိ ပတ်သက်မှု့ကိုလျှော့ချစေနိုင်ပါသည်။

ဤ DaoImp အား အသုံးပြု၍ Entity အားလုံး၏ အခြေခံ CRUD တို့အား အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။ နောက်ရက်များမှပဲ ၎င်းတို့အား Resource အဖြစ် Web အပေါ်တွင် ဖော်ပြနိုင်ရန် JAX-RS နှင့် ဆက်လက်ရေးသားသွားပါဦးမည်။

ဆက်ပါဦးမည်။လေးစားစွာဖြင့်။
မင်းလွင်

No comments:

Post a Comment