# eGovFramework KCCF 코드 패턴 레퍼런스 ## VO 완성 패턴 ```java package kccf.{module}.vo; import kccf.cmm.vo.CmmBaseVO; import lombok.*; @Setter @Getter @ToString @NoArgsConstructor @AllArgsConstructor public class {Module}VO extends CmmBaseVO { /* {한글명} 아이디 */ private String {module}Id; /* {한글명}명 */ private String {module}Nm; /* 지역코드 */ private String areaCode; /* 삭제여부 */ private String deleteAt; /* 등록자 아이디 */ private String regUserId; /* 등록자명 */ private String regUserNm; /* 등록일시 */ private String regDttm; /* 수정자 아이디 */ private String updUserId; /* 수정일시 */ private String updDttm; /* 검색 - {조건명} */ private String search{Field}; /* 권한 관련 */ private boolean canReadOther; private boolean canWrite; private boolean canUpdate; } ``` ## DAO 패턴 ```java package kccf.{module}.dao; import java.util.List; import kccf.cmm.dao.CmmBaseDAO; import kccf.{module}.vo.{Module}VO; import org.springframework.stereotype.Repository; @Repository public class {Module}DAO extends CmmBaseDAO { public List<{Module}VO> select{Module}List({Module}VO vo) { return selectList("kccf.{module}.dao.{Module}DAO.select{Module}List", vo); } public {Module}VO select{Module}Detail({Module}VO vo) { return selectOne("kccf.{module}.dao.{Module}DAO.select{Module}Detail", vo); } public void insert{Module}({Module}VO vo) { insert("kccf.{module}.dao.{Module}DAO.insert{Module}", vo); } public void update{Module}({Module}VO vo) { update("kccf.{module}.dao.{Module}DAO.update{Module}", vo); } public void delete{Module}({Module}VO vo) { delete("kccf.{module}.dao.{Module}DAO.delete{Module}", vo); } public String get{Module}IdSeq() { return selectOne("kccf.{module}.dao.{Module}DAO.get{Module}IdSeq", null); } } ``` ## Service / ServiceImpl 패턴 ```java // Service 인터페이스 public interface {Module}Service { List<{Module}VO> select{Module}List({Module}VO vo); {Module}VO select{Module}Detail({Module}VO vo); void insert{Module}({Module}VO vo); void update{Module}({Module}VO vo); void delete{Module}({Module}VO vo); String get{Module}IdSeq(); } // ServiceImpl @Service @RequiredArgsConstructor public class {Module}ServiceImpl implements {Module}Service { private final {Module}DAO {module}DAO; @Override public List<{Module}VO> select{Module}List({Module}VO vo) { return {module}DAO.select{Module}List(vo); } // ... 나머지 메서드 } ``` ## Controller 완성 패턴 ```java @Controller @RequiredArgsConstructor @RequestMapping(value = "/sec/{module}") public class {Module}Controller extends CmmBaseController { private final {Module}Service {module}Service; private final KccfLoginService kccfLoginService; @RequestMapping(value = "/{module}ListPage.do") public String {module}ListPage({Module}VO searchVO, ModelMap model, HttpSession session) { UserVO userVO = (UserVO)session.getAttribute("user"); if(userVO == null || StringUtils.isAllBlank(userVO.getUserId())) { return "redirect:/login.do"; } // 코드 목록 로딩 CmmnCodeDetailVO cmmVO = new CmmnCodeDetailVO(); cmmVO.setCode("AREA_CODE"); model.addAttribute("areaCodeList", kccfLoginService.selectCodeListAjax(cmmVO)); searchVO.setCanWrite(AuthUtil.canWrite(getUserId(), getSiteSeCode(), getSelMenuId(), "")); model.addAttribute("searchVO", searchVO); return model.getAttribute("hostId") + "/{module}/list{Module}"; } @RequestMapping(value = "/select{Module}ListAjax.do") public String select{Module}ListAjax({Module}VO searchVO, ModelMap model) { List<{Module}VO> list = {module}Service.select{Module}List(searchVO); if(list != null && list.size() > 0) { searchVO.setTotCnt(list.get(0).getTotCnt()); } model.addAttribute("data", list); model.addAttribute("searchVO", searchVO); return "jsonView"; } @RequestMapping(value = "/{module}DetailPage.do") public String {module}DetailPage({Module}VO searchVO, ModelMap model, HttpSession session) { UserVO userVO = (UserVO)session.getAttribute("user"); if(userVO == null || StringUtils.isAllBlank(userVO.getUserId())) { return "redirect:/login.do"; } if(searchVO.get{Module}Id() != null && !searchVO.get{Module}Id().isEmpty()) { model.addAttribute("{module}VO", {module}Service.select{Module}Detail(searchVO)); } searchVO.setCanWrite(AuthUtil.canWrite(getUserId(), getSiteSeCode(), getSelMenuId(), "")); model.addAttribute("searchVO", searchVO); return model.getAttribute("hostId") + "/{module}/{module}Regist"; } @RequestMapping(value = "/insert{Module}.do") public String insert{Module}({Module}VO searchVO, RedirectAttributes redirect) { searchVO.setRegUserId(getUserId()); searchVO.setUpdUserId(getUserId()); if(searchVO.get{Module}Id() != null && !searchVO.get{Module}Id().isEmpty()) { {module}Service.update{Module}(searchVO); } else { searchVO.set{Module}Id({module}Service.get{Module}IdSeq()); {module}Service.insert{Module}(searchVO); } redirect.addAttribute("pageNo", searchVO.getPageNo()); redirect.addAttribute("selMenuId", searchVO.getSelMenuId()); return "redirect:/sec/{module}/{module}ListPage.do"; } @RequestMapping(value = "/delete{Module}.do") public String delete{Module}({Module}VO searchVO, RedirectAttributes redirect) { {module}Service.delete{Module}(searchVO); redirect.addAttribute("pageNo", searchVO.getPageNo()); redirect.addAttribute("selMenuId", searchVO.getSelMenuId()); return "redirect:/sec/{module}/{module}ListPage.do"; } } ``` ## MyBatis Mapper XML 패턴 ```xml INSERT INTO TB_{MODULE} ( {MODULE}_ID, {MODULE}_NM, AREA_CODE, DELETE_AT, REG_USER_ID, REG_DTTM, UPD_USER_ID, UPD_DTTM ) VALUES ( #{module}Id}, #{module}Nm}, #{areaCode}, 'N', #{regUserId}, SYSDATE, #{updUserId}, SYSDATE ) UPDATE TB_{MODULE} SET {MODULE}_NM = #{module}Nm} , AREA_CODE = #{areaCode} , UPD_USER_ID = #{updUserId} , UPD_DTTM = SYSDATE WHERE {MODULE}_ID = #{module}Id} UPDATE TB_{MODULE} SET DELETE_AT = 'Y' , UPD_USER_ID = #{updUserId} , UPD_DTTM = SYSDATE WHERE {MODULE}_ID = #{module}Id} ``` ## 주의사항 - `SYSDATE`: Oracle/Altibase 전용 → MySQL/MariaDB에서는 `NOW()` - `ROW_NUMBER() OVER (...)`: Oracle/Altibase/PostgreSQL 지원 → MySQL 5.7 이하 미지원 (서브쿼리 대체) - `||` 문자열 연결: Oracle/PostgreSQL → MySQL은 `CONCAT()` - 현재 DB 설정은 `egov-com-datasource.xml` 또는 application 설정에서 확인