July 23, 2012

MVC

MVC နှင့် ပတ်သက်လျှင် ကျွှန်တော့်မှာ ရင်နာစရာ အတွေ့အကြုံ ရှိခဲ့ဘူးပါသည်။ လွန်ခဲ့သော ၃ နှစ်ခန့်က ဖြစ်၏။ ကျွှန်တော်သည် အလုပ်ပြောင်းရန် စဉ်းစားနေချိန်ဖြစ်၏။ အင်တာဗျူးတစ်ခုတွင် စာရွက်တစ်ရွက် နဲ့ ဘောပင် တစ်ချောင်း ချပေးပြီး ၁၅မိနစ်အတွင်း MVC နဲ့ပတ်သက်တဲ့ အကြောင်းကို ရေးပါလို့ ဆိုလာပါသည်။

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

ရုတ်တရက် ဘွဲ့ရခါစ တစ်ယောက်လို စာမေးပွဲစစ်လာပါသည်။ ပုံလေးဆွဲ၊ စာလေးရေးနှင့် စာမျက်နှာ တစ်ဝက်စာပင် မရှိ။ ကျွှန်တော့်မှာ ရေးစရာကုန်သွားပါသည်။ ကျွှန်တော်အဲ့ဒီမှာ သိလိုက်ရပါသည်။ ငါဟာ MVC ကိုလည်း သုံးနေတယ်။ အမြဲလည်းကြားနေတယ်။ ကိုယ့်ဟာကိုယ် သိတယ်ပဲ ထင်နေခဲ့တယ်။ တကယ်တမ်းကျတော့ လုံးဝမသိပါလားလို့။ ကျွှန်တော် အဲ့ဒီအလုပ်စာမေးပွဲ မအောင်ခဲ့ပါ။


MVC Model


ယနေ့ ခေတ် MVC သည် Web Application များတွင် Design Pattern အနေဖြင့်၎င်း၊ အာကီတက်ချာ အနေနဲ့၎င်း၊ Framework အနေဖြင့်၎င်း လွန်စွာမှ လူပြောများ ခေတ်စားခဲ့သော အကြောင်းအရာတစ်ခု ဖြစ်၏။ ကျွှန်တော်ကိုယ်တိုင်လည်း အစက MVC သည် Web Application များ၏ အခြေခံဒီဇိုင်း တစ်ခုဟု ထင်နေခဲ့မိ၏။

သို့ရာတွင် MVC ၏ အစမှာ Desktop Application များမှ ဖြစ်ပါသည်။ ကနဦး Object Oriented ဘာသာရပ်တစ်ခု ဖြစ်သော Smalltalk ၏ Windows များစွာကို အသုံးပြုသော Desktop Application များအား ရေးသားရာတွင် စတင်စဉ်းစားခဲ့သော ဒီဇိုင်းတစ်မျိုး မှ စတင်ခဲ့ခြင်း ဖြစ်ပါသည်။ Application အတွင်း ပါဝင်သော Object များအား Model, View နှင့် Controller ဟု တာဝန်များခွဲကာ စဉ်းစားကြပါသည်။


Model


Model ဆိုသည်မှာ Windows ပေါ်တွင် ဖော်ပြပေးနေသော Object ကို ဆိုလိုပါသည်။ သို့ရာတွင် Model Object သည် မိမိသည် မည်သည့်နေရာတွင်ဖော်ပြ၍၊ မည်သည့်ပုံစံဖြင့် ဖော်ပြရမည်၊ မည်သည့် အရောင်ဖြင့် ဖော်ပြရမည် အစရှိသည့် အချက်အလက်များအား ပိုင်ဆိုင်ခြင်းမရှိပါ။ ပြောရမည်ဆိုလျှင် Business Data သက်သက်ကိုသာ ပြုပြင်ပြောင်းလည်းခြင်း၊ Reference လုပ်ခြင်းတို့သည်သာ Model Object ၏ တာဝန် ဖြစ်၏။



View


View Object သည် Model အား မည်သည့်နေရာတွင်၊ မည်သည့်ပုံစံဖြင့် ဖော်ပြရမည်ကို လုပ်ဆောင်ပေးနိုင်သော Object ဖြစ်၏။ အမည်အတိုင်း ဖော်ပြရန်သက်သက် တာဝန်ယူပေးပါသည်။ ဥပမာအားဖြင့် Model ၏ အချက်အလက်များအား၊ ဇယား အဖြစ်ဖော်ပြပေးမည်၊ Line Graph, Ball Graph, Circle Graph အစရှိသဖြင့် ဖော်ပြမည်၊ အစရှိသည်တို့ကို ပြုလုပ်ပေးရန် လိုအပ်ပါသည်။

စာမျက်နှာ အနည်းငယ်သာပါသော အပလီကေးရှင်းများဆိုပါက အချက်အလက်များအား စီမံခန့်ခွဲနိုင်သော Model နှင့် View ကို သာအသုံးပြုသော Pattern များနှင့်ပင် လုံလောက်ပါသည်။ Model View Pattern သည် အဆိုပါ Pattern မျိုးဖြစ်ပါသည်။


Controller


ဤသို့ဆိုလျှင် Controller သည် ဘာကြောင့်လိုအပ်သနည်း။ မည်သည့်တာဝန်ကို ထမ်းဆောင်ရမည်နည်း။ MVC ၏ အစပြုခဲ့ပုံကို ပြန်ကြည့်စေလိုပါသည်။ Data ပုံစံအမျိုးမျိုးနှင့်၊ Windows ပေါင်းများစွာကို အသုံးပြုသော အပလီကေးရှင်းအား ရေးသားရန် MVC ကို စတင်ခဲ့၏။ User ၏ ခိုင်းစေချက် အပေါ် မှုတည်၍ အချက်အလက် Model နှင့် View များအား အပြန်အလှန်ဆက်သွယ်ကာ သင့်တော်သလို ဆက်သွယ်ဖော်ပြ ပေးနိုင်ရန်သည် Controller ၏ တာဝန် တစ်ခု ဖြစ်လာပါသည်။

တနည်းဆိုရသော် Controller သည် Model နှင့် View အား စီမံခန့်ခွဲရန် အသုံးပြုသူ၏ အမိန့်ကို လက်ခံရယူပြီး၊ Model နှင့် View အား အပြန်အလှန် အမိန့်ပေးခိုင်းစေခြင်း အားဖြင့် အပလီကေးရှင်းတစ်ခုလုံးအား စီမံခန့်ခွဲပေးပါသည်။

ဤနည်းအားဖြင့် စတင်ခဲ့သော MVC သည် နောက်ပိုင်းတွင် J2EE ၏ Design Pattern တစ်ခု အဖြစ်အသုံးပြု လာရာမှ၊ Web Application အတော်များများ၏ အခြေခံ ဒီဇိုင်းတစ်ခု အဖြစ်၎င်း၊ Framework တစ်ခု အဖြစ်၎င်း J2EE ၏ MVC Pattern များကိုယ်တိုင်က အခြားသော Design Pattern များအား သုံးစွဲ၍ Softwar အာကီတက်ခြားအဖြစ်၎င်း တဖြည်းဖြည်း အသွင်ပြောင်း လာခဲ့ပါသည်။
ထို့ကြောင့် MVC အား ဤအချိန်တွင် တသမတ်တည်း အဓိပ္ပါယ်ဖွင့်ရန်မှာ လွန်စွာခက်ခဲပါလိမ့်မည်။ သို့ရာတွင် MVC သည် ရှုပ်ထွေးသော User Interface ကို အသုံးပြုသော အပလီကေးရှင်းများအား တည်ဆောက်ရာတွင် အထောက်အကူပြုရန် အသုံးပြုသင့်သော ဒီဇိုင်းတစ်ခုဟု သဘောပေါက်ပြီး၊ မိမိရေးသားလိုသော အပလီကေးရှင်း အပေါ်မှုတည်၍ အသုံးပြုသင့်သော Framework များအား ရွေးချယ် သွားနိုင်ပါလိမ့်မည်။


နမှုနာ အပလီကေးရှင်း


ကျွှန်တော်တို့ ပြီးခဲ့သော နမှုနာအပလီကေးရှင်းကို ပြန်ကြည့်ပါမည်။ Servlet သည် Request ၏ Path Info အားကြည့်ပြီး ဘယ် JSP ဖြင့် ဖော်ပြရမည်၊မည်သည့် လုပ်ဆောင်ချက်ဖြင့် အချက်အလက်များအား တွက်ချက် အသုံးပြုရမည်ဟု ခွဲခြားရေးသားခဲ့ပါသည်။

 အချက်အလက်များအား ဖော်ပြပေးသော JSP များသည် View ဖြစ်၍၊ မည်သည့်အချက်အလက်ကို မည်သည့် View တွင် ဖော်ပြရမည်ဟု လုပ်ဆောင်ပေးနိုင်သော Servlet သည် Controller နှင့် Model ၏ နေရာတွင် တည်ရှိပြီး MVC ၏ ပုံစံတွင်ရှိသည်ဟု ဖော်ပြခဲ့၏။

အထက်ပါ နမှုနာတွင် တည်ဆောက်ပုံသည် Model နှင့် Controller အား မရှင်းမရှင်း ရေးသားထားသည်။ ထို့ကြောင့် ဘယ်အတိုင်းအတာအထိ Model က လုပ်သင့်သည်၊ Controller ကလုပ်သင့်သည် ဆိုသည်မှာ မကွဲပြားပေ။ အကယ်၍ ဤနမှုနာအတိုင်း စာမျက်နှာ လေးငါးခုသာရှိသော အပလိုဆိုလျှင် ကိစ္စမရှိ။

စာမျက်နှာ အများအပြားအား အသုံးပြုမည်၊ ထို့အပြင် Developer ပေါင်းများစွာဖြင့် ရေးသားရမည့် အပလီကေးရှင်းဆိုပါက ဤကဲ့သို့ရေးသားပုံမျိုးသည် လွန်စွာမှ အန္တရယ်ရှိပါသည်။ ပြုပြင်ရန် ခက်ခဲသလို၊ စာမျက်နှာတစ်ခု တိုးတိုင်း Controller အား ပြုပြင်ရမည် ဆိုလျှင် အတော်လေးကို ရှုပ်ထွေးသွားပါတော့မည်။ ထို့အတွက် ဤနေရာတွင် Model နှင့် Controller အား တိတိကျကျခွဲခြား တာဝန်ပေးထားရန် လိုအပ်ပါသည်။

ကျွှန်တော်တို့ ဒီတစ်ခေါက်တွင် Controller နှင့် Model အား ခွဲထုတ်ပြီး၊ Flow Propertiesကဲ့သို့ပင် Business Logic Properties အား ပြင်ဆင်ပြီး၊ Business Logic IDအပေါ်မှုတည်၍ အသုံးပြုမည့် Business Model အား ခေါ်ယူပါမည်။ ထို Model Object အား Input အချက်အလက်များ ပေးပြီး၊အလုပ်လုပ်ခိုင်းပါမည်။ ပြီးပါက ရရှိလာသောရလဒ်အား ရယူကာ Flow Properties တွင် သတ်မှတ်ထားသော JSP View အား ပေးပြီး ဖော်ပြစေမည် ဖြစ်ပါသည်။



Controller


ဤနမှုနာတွင် EM_Controller ကလပ်စ်သည် Controller ၏ နေရာအား ရယူထားပါသည်။ EM_Controller သည် HTTPServlet အား Extends လုပ်ထားသော ကလပ်စ်တစ်ခု ဖြစ်ပြီး၊ Request အပေါ်မှုတည်၍ သင့်တော်သော Model နှင့် View အား ခေါ်ယူကာ အလုပ်လုပ်စေရန် တာဝန် ယူထားရပါသည်။

EM_Controller#init သည် Servlet အား အင်းစတန့်စ် အဖြစ် မွေးဖွားစေရာတွင် ခေါ်ယူရမည့် လုပ်ဆောင်ချက်ဖြစ်ပြီး၊ အတွင်းပိုင်းတွင် အသုံးပြုလိုသား Properties ဖိုင်များနှင့် SQL များအား မံမိုရီပေါ်သို့ ခေါ်ယူပါသည်။ ဤနမှုနာတွင် MVC အပြင် Database ကိုလည်း ပြောင်းလည်း အသုံးပြုထားပါသည်။ ဤဘလောဂ်တွင် MVC အကြောင်းကို အဓိကထား ဖော်ပြလိုပါသဖြင့် SQL နှင့် ပတ်သက်သည်များကို နောက်ဘလောဂ်များဖြင့် ဖော်ပြသွားပါမည်။

EM_Controller.java
package com.mmju.jsp.ep6;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class EM_Controller extends HttpServlet {

 private static final long serialVersionUID = 1L;
 private Properties flowsProp;
 private Properties modelConf;

 public static Map<String, String> SQL_CONF = new HashMap<String, String>();;

 @Override
 public void init() throws ServletException {

  flowsProp = new Properties();
  modelConf = new Properties();
  final String _extension = ".sql";
  BufferedReader br = null;
  try {
   // load flows
   flowsProp.load(getServletContext().getResourceAsStream(
           "/WEB-INF/conf/apl/flows.properties"));

   // load models
   modelConf.load(getServletContext().getResourceAsStream(
           "/WEB-INF/conf/apl/model.properties"));

   // load sql
   File sqlPath = new File(getServletContext().getRealPath(
           "/WEB-INF/conf/sql"));
   File[] sqlFiles = sqlPath.listFiles(new FilenameFilter() {
    @Override
    public boolean accept(File dir, String name) {
     return name.endsWith(_extension);
    }
   });

   for (int i = 0; i < sqlFiles.length; i++) {
    String name = sqlFiles[i].getName().replace(_extension, "");
    StringBuilder sb = new StringBuilder();
    br = new BufferedReader(new InputStreamReader(
            new FileInputStream(sqlFiles[i])));
    String line = null;

    while (null != (line = br.readLine())) {
     sb.append(line);
    }

    EM_SqlConf.put(name, sb.toString());
   }

  } catch (Exception e) {
   throw new RuntimeException();
  } finally {
   if (null != br) {
    try {
     br.close();
    } catch (IOException e) {
    }
   }
  }
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException {
  this.doPost(req, resp);
 }

 @SuppressWarnings("unchecked")
 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException {

  // set param ref_key
  String businessID = this.getBusinessID(req.getRequestURI());
  req.setAttribute("ref_key", businessID);

  // getModel
  List<EM_Model> models = this.getModels(businessID);

  for (EM_Model model : models) {
   // model#setInput
   model.setInputs(req.getParameterMap());

   // model#doBusiness
   model.doBusiness();
  }
  // set View
  this.setView(models, req, resp);
 }

 /**
  * To get Model Classes setting in model configuration
  * 
  * @param businessIDs
  * @return
  */
 private List<EM_Model> getModels(String businessID) {
  try {
   List<EM_Model> models = new ArrayList<EM_Model>();
   String names = (String) this.modelConf.get(businessID);
   if (null != names) {
    String[] classNames = names.split(",");
    if (null != classNames) {
     for (String name : classNames) {
      System.out.println(name);
      EM_Model model = (EM_Model) Class.forName(name.trim())
              .newInstance();
      if (null != model)
       models.add(model);
     }
    }
   }
   return models;
  } catch (Exception e) {
   e.printStackTrace();
   throw new RuntimeException();
  }
 }

 /**
  * setting view
  * <ul>
  * <li>getting output from business logic model</li>
  * <li>set the result to HttpRequest</li>
  * <li>despatch request to view</li>
  * </ul>
  * 
  * @param outputs
  * @param req
  * @param resp
  * @throws ServletException
  * @throws IOException
  */
 private void setView(List<EM_Model> models, HttpServletRequest req,
         HttpServletResponse resp) throws ServletException, IOException {
  for (int i = 0; i < models.size(); i++) {
   // Outputs
   Map<String, Object> outputs = models.get(i).getOutPuts();
   Iterator<String> itr = outputs.keySet().iterator();
   // Set Outputs
   while (itr.hasNext()) {
    String key = itr.next();
    req.setAttribute(key, outputs.get(key));
   }
  }
  this.getDispatcher(req.getRequestURI()).forward(req, resp);
 }

 /**
  * getting business logic id
  * 
  * @param reqPathInf
  * @return
  */
 private String getBusinessID(String reqPathInf) {
  if (null != reqPathInf && !reqPathInf.isEmpty()) {
   String[] infos = reqPathInf.split("/");
   for (int i = 0; i < infos.length; i++) {
    if (infos.length - 1 == i) {
     return infos[i].replace(".em", "");
    }
   }
  }
  return null;
 }

 /**
  * getDispatcher
  * 
  * @param reqInfo
  * @return
  */
 private RequestDispatcher getDispatcher(String reqInfo) {
  if (null != reqInfo && !reqInfo.isEmpty()) {
   String[] infos = reqInfo.split("/");
   StringBuilder sb = new StringBuilder("/jsp");
   for (int i = 0; i < infos.length; i++) {

    if (infos[i].length() > 0) {
     sb.append("/");
     if (infos.length - 1 == i) {
      String key = infos[i].replace(".em", "");
      sb.append(flowsProp.getProperty(key));
     } else {
      sb.append(infos[i]);
     }
    }
   }
   return getServletContext().getRequestDispatcher(sb.toString());
  }
  return null;
 }
}
ဤနမှုနာတွင် အဓိက အလုပ်လုပ်နေသည်မှာ စာကြောင်း ၉၀ရှိ doPost လုပ်ဆောင်ချက်ပင် ဖြစ်၏။ စာကြောင်း ၉၄ တွင် HttpServletRequest အတွင်းမှ Business ID အား ရယူပါမည်။ ထို Business ID နှင့် flows.properties အတွင်းတွင် ဖော်ပြမည့် JSP အား သတ်မှတ်ထားပြီး၊ model.properties တွင် အသုံးပြုမည့် Model အား သတ်မှတ် ရေးသားထားပါသည်။

ပြီးပါက စာကြောင်း ၉၈ဖြင့် အသုံးပြုမည့် Model အား ရယူပါသည်။ Business ID များတွင် Model များအား အသုံးပြုသည့်အခါလည်း ရှိမည်၊ အသုံးမပြုပဲ Flow ကို သာအသုံးပြုလိုသည့်အခါမျိုးလည်း ရှိပါမည်။ ဤဥပမာတွင် edit, confirm နှင့် details အစရှိသည့် Business ID များသည်၊ Model များအား အသုံးပြုရန်မလိုပေ။ လက်ရှိ အချက်အလက်များအား အခြားသော View ဖြင့် ပြောင်းလည်း ဖော်ပြရုံသာ ဖြစ်သည်။ ထိုအခါမျိုးတွင် flow.properties တွင်သာ ဖော်ပြလိုသည့် View အားရေးသားပြီး၊ model.properties တွင် အထွေအထူး ရေးသားရန် မလိုအပ်ပါ။

တဖန် add, delete နှင့် update တို့သည်လည်း လုပ်ဆောင်ချက်များ အပြီးတွင် ကားလစ်အား ရယူရန် လိုအပ်ပါသည်။ ထို့ကြောင့် Model နှစ်ခုအား တစ်ပြိုင်နက်တည်း အသုံးပြုရန် လိုအပ်ပါသည်။ ထိုအခါမျိုးတွင် add တွင် add နှင့် select လုပ်မည့် model အား ကော်မာခြားပြီး ရေးသားရန် လိုအပ်ပါသည်။ ထိုအခါမျိုးတွင် add လုပ်ပြီး select လုပ်ကာ ရလဒ်အား flow တွင် သတ်မှတ်ထားသော JSP ဖြင့် ဖော်ပြမည် ဖြစ်ပါသည်။


model.properties
list=com.mmju.jsp.ep6.model.Md_select
update=com.mmju.jsp.ep6.model.Md_Update,com.mmju.jsp.ep6.model.Md_select
delete=com.mmju.jsp.ep6.model.Md_Delete,com.mmju.jsp.ep6.model.Md_select
add=com.mmju.jsp.ep6.model.Md_add,com.mmju.jsp.ep6.model.Md_select
စာကြောင်း ၁၀၀ တွင် ရရှိထားသော Model များအား for ဝါကျကို အသုံးပြုကာ တစ်ခုဆီ၊ စာကြောင်း ၁၀၂ ဖြင့် Input Data များအား ပေးကမ်းကာ၊ EM_Model#doBusiness ဖြင့် သက်ဆိုင်ရာ လုပ်ငန်းဆောင်တာများ အား လုပ်ဆောင်စေပါသည်။ နောက်ဆုံးတွင် စာကြောင်း ၁၀၈ ဖြင့် setView လုပ်ဆောင်ချက်အား ခေါ်ယူကာ Model ၏ ရလဒ်အား Request အတွင်းသို့ ဖြည့်စွက်ကာ flow.properties တွင် သတ်မှတ်ထားသော JSP အား forward လုပ်လိုက်ခြင်းသာဖြစ်၏။


Model


ဤနမှုနာထဲတွင် Model များအား အုပ်စုတစ်ခု အနေဖြင့် အသုံးပြုနိုင်ရန် EM_Model ဟု Abstract Class တစ်ခု အားပြင်ဆင်ထားပါသည်။ ထိုအထဲတွင် Model အဖြစ် မရှိမဖြစ်လိုအပ်သည့် လုပ်ဆောင်ချက်များ၊ နှင့် အချက်အလက်များအား သက်မှတ် ရေးသားထားပါသည်။ Model အလိုက် ပြောင်းရေးရန် လိုအပ်သည့် လုပ်ဆောင်ချက်ကိုသာ abstract လုပ်ဆောင်ချက်အဖြစ် ရေးသားထားပြီး၊ အမွေဆက်ခံသည့် Sub Class သည် အထက်ပါ လုပ်ဆောင်ချက်ကို မဖြစ်မနေ ဖြည့်စွက် ရေးသားရန် လိုအပ်ပါသည်။

EM_Model.java
package com.mmju.jsp.ep6;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public abstract class EM_Model {

 protected Map<String, Object> inPuts;
 protected Map<String, Object> outPuts;
 
 public EM_Model(){
  outPuts = new HashMap<String, Object>();
 }

 public void setInputs(Map<String, Object> input) {
  this.inPuts = input;
 }

 public Map<String, Object> getOutPuts() {
  return this.outPuts;
 }

 /**
  * Main Business Logic
  */
 public abstract void doBusiness();

 /**
  * getConnection
  * 
  * @return JDBC Connection
  */
 protected Connection getConnection() {
  try {
   Context ctx = new InitialContext();
   DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ezjsp");
   return ds.getConnection();
  } catch (Exception e) {
   e.printStackTrace();
   throw new RuntimeException();
  }
 }
 
 protected void setOutputs(String key, Object value) {
  outPuts.put(key, value);
 }
 
 protected Map<String, Object> getInputs() {
  return this.inPuts;
 }
 
 protected String getStringValue(String key) {
  Object value = this.inPuts.get(key);
  if(null != value && value instanceof String []) {
   String [] params = (String [])value;
   if(params.length > 0)
    return params[0];
  }
  return null;
 }
}
အထက်ပါ ကလပ်စ်တွင် မံဘာ အနေဖြင့် inputs နှင့် outputs Map တို့အား ပိုင်ဆိုင်ပြီး၊ Controller မှ ခေါ်ယူရန် setInputs, getInputs နှင့် doBusiness လုပ်ဆောင်ချက်တို့အား ပိုင်ဆိုင်ပါသည်။ doBusiness သည် Abstract လုပ်ဆောင်ချက်ဖြစ်ပြီး၊ Extends လုပ်သည့် Sub Class ဘက်တွင် ဖြည့်စွက် ရေးသားရပါမည်။ တဖန်၊ Sub Class များတွင် ဘုံအဖြစ်အသုံးပြုနိုင်ရန် Database Connection ကို ရယူနိုင်သော getConnection နှင့် setOutputs, getInputs နှင့် getString လုပ်ဆောင်ချက်များအား ပိုင်ဆိုင်ပါသည်။

ဤနမှုနာထဲတွင် အထက်ပါ EM_Modelအား Extends လုပ်ပြီး Model အဖြစ်အသုံးပြုလိုသည့် ကလပ်စ် များမှာ အောက်ပါအတိုင်းဖြစ်ပါသည်။
နမှုနာ အဖြစ် EM_Model အား Extend လုပ်ထားသော Md_add.java အား လေ့လာကြည့်ပါမည်။

Md_add.java
package com.mmju.jsp.ep6.model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.mmju.jsp.ep6.EM_Model;
import com.mmju.jsp.ep6.EM_SqlConf;

public class Md_add extends EM_Model {

 @Override
 public void doBusiness() {

  Connection conn = null;

  // build sql
  try {
   conn = getConnection();
   PreparedStatement pst = conn.prepareStatement(EM_SqlConf
           .getSql("Md_add_SQLI_001"));
   pst.setString(1, getStringValue("brand"));
   pst.setString(2, getStringValue("model"));
   pst.setString(3, getStringValue("year"));
   
   if(pst.executeUpdate() < 0) {
    throw new RuntimeException("Fail to insert Query.");
   }
  } catch (SQLException e) {
   throw new RuntimeException(e.getMessage());
  } finally {
   if(null != conn) {
    try {
                 conn.close();
                } catch (SQLException e) {
                }
   }
  }
 }

}
Md_add သည် Car အချက်အလက်များအား အသစ် ဖြည့်စွက်ရန် တာဝန်ကျသော Data Model ကလပ်စ် ဖြစ်ပါသည်။ EM_Model ကလပ်စ်အား Extends လုပ်ထားပြီး၊ doBusiness လုပ်ဆောင်ချက်အား Override လုပ်ထားပါသည်။ Controller မှ ခေါ်ယူသည့် အခါတွင် အလုပ်လုပ်မည့် လုပ်ဆောင်ချက်ဖြစ်သည်။

အတွင်းပိုင်းတွင် Super Class ၏ getConnection ဖြင့် Database Connection Object အား ခေါ်ယူကာ၊ PrepareStatement အော့ဘဂျက်အား ပြင်ဆင်ပါသည်။ EM_SqlConf သည် Sql ဖိုင်များအား ID ဖြင့် တွဲကာ Framework အတွင်းတွင် သိမ်းဆည်းထားသော Static Class တစ်ခုဖြစ်ပါသည်။ MVC အကြောင်းကို အဓိက ဖော်ပြလိုပါသဖြင့် ဤနေရာတွင် အသေးစိတ် မရှင်းတော့ပါ။

တဖန် စာကြောင်း ၂၂မှ ၂၄အထိ Request Parameter များအား ရယူကာအသီးသီး PrepareStatement Object တွင် ဖြည့်စွက်ရေးသားပါသည်။ ပြီးပါက စာကြောင်း ၂၆ဖြင့် executeUpdate လုပ်ဆောင်ချက်ဖြင့် Database အား Update လုပ်ပါသည်။ ဤနည်းအားဖြင့် အသီးသီး အချက်အလက်များအား ဖြည့်စွက်ခြင်း၊ပြုပြင်ခြင်း၊ ဖျက်စီးပစ်ခြင်းနှင့် ရှာဖွေခြင်းတို့ကို လုပ်ဆောင်စေပါသည်။

ဤနည်းအားဖြင့် Model များမှ လုပ်ဆောင်ထားသော ရလဒ်များအား Controller မှတဆင့် getOutputs ဖြင့် ရယူကာ သက်ဆိုင်ရာ View ဆီသို့ ပေးပို့၍ ပုံဖော်နေခြင်း ဖြစ်ပါသည်။ View နှင့် ပတ်သက်သည့် အကြောင်းအရာများမှာ ပြီးခဲ့သော အခန်းမှ များစွာပြောင်းလည်းခြင်း မရှိပါသဖြင့် အသေးစိတ်မဖော်ပြတော့ပါ။

JSP နှင့် သိပ်ပြီး မပတ်သက်သောကြောင့် အများကြီးကျော်၍ ရေးသားသွားပါသည်။  အကယ်၍ နားမလည်သည့်နေရာများ ရှိခဲ့ပါက ဘလောဂ်မှတဆင့်သော်၎င်း၊ Facebook မှ တဆင့်သော်၎င်း မေးမြန်းနိုင်ပါသည်။

Project Source
https://github.com/minlwin/mmju/tree/master/jsp-tutorials

နမှုနာ စမ်းသပ်ရန်
http://jsp-tutorials.minlwin.cloudbees.net/


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

No comments:

Post a Comment