블로그 이미지
숏퐁숑

카테고리

분류 전체보기 (70)
게임기획자 준비 (18)
게임기획 참고자료 (7)
프로그램 (33)
숨쉬기 활동 (10)
Total
Today
Yesterday

달력

« » 2025.9
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

공지사항

태그목록

최근에 올라온 글

간단하게 정리하기 어려운 내용인것 같다. 토비의 스프링 프레임워크 책을 보아도 이해안가는 부분도 많다.

하지만 현재 전자정부 프레임워크를 쓰면서 기존의 내용을 알고 정리해 놓으면 좋을것 같아서 정리해 보려고 한다.


MVC 개념이란 무엇일까?

Spring이란 무엇일까?  SPRING MVC란? 


MVC 개념은 화면에서 보여주는 V(View), 데이터 처리관리는 M(Model)

V(View)와 M(Model) 를 연결시켜주는 C(Controller)  각 첫글자를 따서 MVC 라고 한다.

MVC개념은 User Interface 부분을 담당하는 부분과 실제 처리가 일어나는 부분을 최대한 서로 분리시켜 디자이너와 프로그래머 사이에 종속성을 최대한 줄이기 위한 방법론 중 하나이다. 또한 웹 개발을 하면서 클라이언트에서 요청시 처리 로직을

거쳐 데이타 처리를 하여 화면에 매핑시켜주는 일련의 반복적인 과정을 MVC 개념이라고 하겠다. 


Spring은 간단히 스프링이라 지칭하지만 정확하게는 스프링 프레임워크 (Spring Framework) 라고 하는 것이 정확한 표현이다.

즉, 스프링은 자바 프레임 워크중 한 종류를 말한다.  프레임 워크에는 스트러츠, 스트러츠2, 스프링 등 여러 종류가 있는데, 처음

회사에 들어오기 전에는 스트러츠와 스트러츠2로 웹개발을 했던 기억이 있다. 회사에 들어와서는 스프링 2.5 부터시작해서 3.0

지금은 전자정부 프레임워크를 사용하기까지 다양한 자바 프레임워크를 경험해본 결과... 자바기반의 프레임 워크 중에는 스프링프레임워크가 가장 확장성이 좋고 사용하기 좋은 것 같다.  프레임워크의 버전이 올라갈 수록 개발자가 할 일과 신경쓸일이 줄어드는 것은 분명하다.(단, 잘 설계되어진 프레임워크를 사용한다는 가정)   많은 기능(보안,로그,라이브러리관리 등등) 들을 지원해 주기 때문에 공통/표준 설계자가 처음 프레임워크 설계만 잘해서 준다면 개발자들은 별 신경 없이 개발에만 집중할 수 있다. 토비의 스프링프레임워크 3.1에서는 자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크라고 정의하고 있다.   프레임워크란 집을 짓는것을 예로 들면 말 그대로 집의 틀을 구성한다는 의미인데 그 틀을 어떻게 구성하느냐에 따라서 살만 붙히면 집이 완성되기 때문에 중요한 부분을 차지하는 것은 분명하다. 스프링 프레임워크를 정리하기엔 너무 많은 내용(POJO,AOP,DI,IoC 등등)들이 있으니 나중에 다시 보도록 하고, 본론으로 들어가 SPRING MVC 패턴이 무엇인지 정리해 보려 한다.


Spring MVC는 위에서 설명한 기본적인 요소 Model,View,Controller외에도 많은 컴포넌트들이 있다.

DispatcherServlet, HandlerMapping, Controller,Interceptor,Viewresolver,View 등 컴포넌트들이 존재하며

각 역활이 명확하게 분리되어 있다.


아래 설명은 각 컴포넌트들의 역활에 대한 설명이다.

 


아래 그림은 스프링MVC 패턴의 흐름을 잘 설명해주는 그림으로 정말 여러번 보았지만 꾀 오랫동안 이해 가지 않았던 MVC흐름도이다. 지금 전체적인 그림은 아니지만 MVC 각 모듈이 어떤 일들을 하면서 진행되는지 알 수 있다.



클라이언트가 요청을 하면 위 그림처럼 DispatcherServlet이 가장 먼저 요청을 받아 어느 Controller에서 일을 진행할지 정하기위해 HandlerMapping을 통해 리턴 받는다. Controller가 정해지면 해당 컨트롤러에서 인터페이스를 호출하고, 인터페이스 구현부를 호출하여 비즈니스 로직(Impl)을 수행하게 된다. 비즈니스 로직 단계에서 필요한 데이터들은 Dao를 호출하여

데이터 처리를 하며 DB에서 가져온 데이터를 Controller단계까지 가져와 화면과 매핑해주게 된다.

이때 데이터들을 담는 통?을 모델(model)이라고 하며 모델에 담겨온 정보들을 View Resolver에서 해당 화면과 매핑하는

작업을 하여 결과값을 리턴 해주고 마지막으로 데이터가 담겨있는 Model을 View로 던져주면 모든 클라이언트 Request 에 대한 Response 작업이 완료되어진다. 크게 클라이언트 요청이 시작되면 Presentation Layer => Business Layer => Data Layer 순으로 흘러가며 작업이 이루어 지는데 간단하게 정리해 보았다. 참고로 위의 그림은 Presentation Layer에서 클라이

언트 요청이 들어왔을때 이루어지는 흐름만 표현되어져 있다.


정리해 본다고 글을 적어보긴 했는데 정리하면서도 느끼는 것이지만 역시나 어렵다.  정리하자면 프레임워크에는 스트러츠, EJB,

스트러츠2, 스프링 등이 있고, 대부분 프로젝트에서 자바기반 프레임워크로는 가장 효츌적인 스프링프레임워크를 사용하고 있다.

물론 전자정부 프레임워크를 도입해 쓰기 시작했지만...

이 스프링프레임워크를 이해하기위해 Spring MVC 패턴에 대해 공부해 보았는데 더 깊은 이해를 위해서는 토비의 스프링프레임워크 3.5를 추천한다. 앞으로 클라우드 기술 표준을 잡기위해 공부해야할 부분이 많이 있는데~  다음에 시간이 되면 스프링프레임워크가 무엇이며 전자정부 프레임워크가 왜 나오게 되었는지에 대해서 간단히 정리해 보도록 하겠다.

Posted by 숏퐁숑
, |

CONCAT 함수는 입력되는 두 문자열을 연결하여 반환한다.

문자열의 데이터타입은 CHAR, VARCHAR2, NCHAR, NVARCHAR2, CLOB, NCLOB이며, 두 문자열 데이터 타입이 같으면, 그와 같은 데이터타입을 반환한다. 하지만 입력되는 두 문자열의 데이터타입이 다를 경우 NCLOB 데이터타입으로 반환된다.

 

【형식】

CONCAT( char1, char2 )

 

 

【예제】

SQL> select concat('My name is','홍길동') from dual;

-----------------------------------------------------------------

My name is 홍길동

 

 

단순히 문자열을 연결하여 반환하는 함수로? CONCAT는 오라클에서 자주 사용하는 익숙한 함수이다.

오늘 정리하고 싶은 WM_CONCAT 함수는 데이터가 그룹화 되어져 있을 때 여러행(Row)의 값을 하나의 컬럼으로 합쳐서

조회 할 수 있는 막강한 기능이라 정리해 보고자 한다.

 

예제) 아래 예제는 각 부서의 사람들의 이름을 한 ROW에 합쳐서 보여주고 싶을 때 ...

 

table name: dept_tb
dept_name || emp_name
=========================
인사과         영수
인사과         철수
인사과         민수
인사과         길동
=========================
 

SELECT wm_concat(emp_name)
FROM dept_tb
GROUP BY dept_name;
※ 단, 여기서 select 결과가 다음과 같이 'oracle.sql.CLOB@e62121' ? clob의 주소값을 반환하고 있는 경우가 있는데... 
이때, TO_CHAR로 감싸서 반환해주면 해결된다! 혹시 그래도 해결이 안된다면... 전자정부프레엠워크 사용시 
Oracle의 경우는 iBatis를 위한 sqlMapClient bean 설정 시 다음과 같이 lobHandler를 등록해 주어야 한다. 
(ex: context-sqlMap.xml)  보통은 공통 잡는 분들이 프레임워크 잡을떄 당연 추가하겠지만 혹시나..!!! 

<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" />

SELECT to_char(wm_concat(emp_name))
FROM dept_tb
GROUP BY dept_name;

 

[결과]

 

===============================
dept_name || emp_name
===============================
인사과         영수,철수,민수,길동
===============================

콤마 제거하고 조회 하고 싶을땐 (replace나 translate 함수) : 문자열을 치환해 주는 기능을 하는 표현식
※ 단순 문자열 치환 : TRANSLATE('대상문자열', '비교문자', '바꿀문자')?
SELECT translate(wm_concat(emp_name),'a,','a ')
FROM dept_tb
GROUP BY dept_name;
[결과]?

==============================
dept_name || emp_name
==============================
인사과     영수철수민수길동
=============================

WM_CONCAT 함수에 대해 정리해 보았다. 알면 정말 유용한 오라클 함수들!! 모르면 정말 어떻게 해야할지 
많은 고민들로 시간을 보내는 경우가 허다한데... 한 번 잘 정리해 놓고 이용하면 좋을 듯 싶다!

'프로그램 > ORACLE' 카테고리의 다른 글

TNS 리스너가 없습니다.  (0) 2016.12.16
오라클 sysdba접속 방법  (0) 2016.12.16
[오라클] TRIGGER 구문 정리  (0) 2016.11.30
[오라클] MERGE INTO 구문 정리  (0) 2016.11.30
[Oracle]오라클 잡 스케줄러 생성  (0) 2016.11.30
Posted by 숏퐁숑
, |
트리거 구문 정리해 보려 한다. 잘 알아두면 유용하게 쓰이는 오라클 구문이기에 이렇게 정리하는 것이 큰 도움이 될 것 같다.

오라클 JOB을 걸면 일정 주기마다 DML(INSERT,UPDATE,DELETE) 작업을 수행하게 하여 TABLE에 데이터 작업을 해줄 수 있다. 일정 주기나 시간이 아니라, TABLE에 어떤 이벤트가 발생했을 때 알아서 오라클에서 내가 정의 해놓은 작업들을 수행해 준다면 얼마나 좋을까? .... 바로 이때 사용 할 수있는 오라클 구문에는 트리거(TRIGGER)가 있다. 

 

1. 트리거(TRIGGER) 정의

 

- 테이블에 어떤 이벤트가 발생했을 때, 자동으로 사용자가 정의한 PL/SQL 명령을 실행 할수 있는 구문이다. 

 

 

2. 트리거(TRIGGER)  생성 구문

 

CREATE [OR REPLACE] TRIGGER 트리거명 [BEFORE | AFTER]
triggering-event[Insert,delete,update] ON 테이블명
[Referencing OLD AS {변경전 값을 참조하는 변수명} NEW AS {변경 후 값을 참조하는 변수명}]
[FOR EACH ROW]

[WHEN (condition)]?
DECLARE
--변수선언
BEGIN
--트리거 PL/SQL 명령 작성
EXCEPTION
END;

 

#구문에 대한 상세 설명#

  • CREATE [OR REPLACE] TRIGGER [schema.]trigger : 트리거 생성, 재생성 명령이다?
  • BEFORE : INSERT, UPDATE, DELETE문이 실행되기 전에 트리거가 실행 된다.
  • AFTER : INSERT, UPDATE, DELETE문이 실행된 후 트리거가 실행 된다.
  • trigger_event : INSERT, UPDATE, DELETE 중에서 한 개 이상 올 수 있다.
  • FOR EACH ROW : 이 옵션이 있으면 행 트리거가 된다.

     - 행수준 트리거(Row -Level Triggers) : 트랜잭션내의 각 행에 대해 한 번만 수행(컬럼의 각각의 행의 데이터 행 변화가 생길 때마다

                                                           실행되며,각 데이터 해의 값을 제어할 수 있다.)
     - 문장수준 트리거(Statement-level Triggers) : 트랜잭션내에서 한번만 수행되며, 컬럼의 각 데이터 행을 제어 할 수 없다.

  • [WHEN (condition)]] : 데이터의 처리유형 이외의 조건을 삽입할 경우에 사용???????????

    ※ 따라서, 위의 옵션을 어떻게 사용하느냐에 따라 만들수 있는 트리거 유형은

    트리거 이벤트(INSERT,UPDATE,DELETE) 3종류, FOR EACH ROW 유무에 따른 2종류, Before와 After에 대해 2종류로

    3*2*2 = 12가지 유형을 만들 수 있다.


    3. 트리거(TRIGGER)  생성시 고려사항

     

    1. 트리거는 각 테이블에 최대 3개까지 가능하다

    2. 트리거 내에서는 COMMIT,ROLLBACK 문을 사용할 수 없다.

    3. 이미 트리거가 정의된 작업에 대해 다른 트리거를 정의하면 기존의 것을 대체한다.

    4. 뷰나 임시 테이블을 참조할 수 있으나 생성 할 수는 없다.

    5. 트리거 동작은 이를 삭제하기 전까지 계속된다.

     

    4. 트리거(TRIGGER)   활성 / 비활성화

     

    ALTER TRIGGER [schema.]trigger DISABLE;   ==> 비활성화

    ALTER TRIGGER [schema.]trigger ENABLE; ==> 활성화

     

    5. 트리거(TRIGGER)  상태  확인

     

    select table_name, status from user_triggers; => 테이블 명과, 트리거 활성 상태를 확인 할 수 있다.

     

    6. 트리거(TRIGGER)  삭제 구문

     

    DROP TRIGGER [schema.]trigger

     

    7. 트리거(TRIGGER)  작성 예문

     

    예문 1) 테이블 변경 이력 관리를 위한 TRIGGER 구문

     

    ?CREATE OR REPLACE TRIGGER NAMDM.RECORD_CHANGE_LOG_TO_MDMTB090
    AFTER DELETE OR INSERT OR UPDATE
    OF VALUE
    ON NAMDM.MDMTB010
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    BEGIN
      -- your code here
      -- (Trigger template "Default" could not be loaded.)  
     
      IF :NEW.VALUE != :OLD.VALUE THEN   -- 값이 변경된 경우만 저장!!!
        INSERT INTO mdmtb090
        (
          SEQ, ITEM_ID, ATTR_ID, SCOPE,
          OLD, NEW, BIGO, CHG_EMP, DAT 
        )
        VALUES
        (
          MDM_TRIGGER_SEQ.NEXTVAL, NVL(:NEW.ITEM_ID,:OLD.ITEM_ID), NVL(:NEW.ATTR_ID,:OLD.ATTR_ID), NVL(:NEW.SCOPE,:OLD.SCOPE),
          :OLD.VALUE, :NEW.VALUE, '', :NEW.CHG_EMP, SYSDATE
        );
      END IF;
    END;

     

    예문 2) 테이블에 이벤트 발생시 다른 테이블에 MERGE 하기 위한 TRIGGER 구문

     

    CREATE OR REPLACE TRIGGER NATEST.CALL_ACT_CONFIRM
    AFTER DELETE OR INSERT OR UPDATE
    OF IF_FLAG
    ON NATEST.TEST_IF
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    BEGIN
       
         IF :NEW.IF_FLAG = 'S' AND (:NEW.REVISION_ID <> '000' OR :NEW.REVISION_ID <> 'MRP' OR  :NEW.REVISION_ID <> 'EXT') THEN
            --SP_TESTTB020_PROCESS('ACT', 'CONFIRM',:NEW.M00001,:NEW.REVISION_ID,:NEW.M00069,:NEW.ASSINGEE_ID);
              /* 4-2-1. TESTTB010로 데이터 복사 */
            MERGE INTO TESTTB010 ORG
            USING (
                        SELECT    T1.ITEM_ID,
                                T1.ATTR_ID,
                                T1.SCOPE,
                                T1.VALUE    WORK_VALUE,
                                T1.CHG_EMP,
                                T1.CHG_DATE
                        FROM    TESTTB011    T1,
                                TESTTB020    T2
                        WHERE    T1.ITEM_ID    = T2.ITEM_ID
                        AND        T1.REV_NO    = T2.REV_NO
                        AND        T2.STATUS    = 'A'
                        AND        T1.ITEM_ID    = :NEW.M00001
                        AND        T1.REV_NO    = :NEW.REVISION_ID    
                        AND        T2.PLANT    = :NEW.M00069     
                        AND        (T1.SCOPE = 'G' OR T1.SCOPE = 'C' OR T1.SCOPE = T2.REGION OR T1.SCOPE = T2.COMPANY OR T1.SCOPE = T2.PLANT)
                  ) TMP
              ON  (
                        ORG.ITEM_ID    = TMP.ITEM_ID
                  --AND    ORG.REV_NO     = TMP.REV_NO
                  AND    ORG.ATTR_ID    = TMP.ATTR_ID
                  AND    ORG.SCOPE    = TMP.SCOPE
                  ) WHEN MATCHED THEN
                         UPDATE
                            SET    ORG.VALUE        = TMP.WORK_VALUE,
                                ORG.CHG_EMP        = TMP.CHG_EMP,
                                ORG.CHG_DATE    = TMP.CHG_DATE
                    WHEN NOT MATCHED THEN
                    INSERT
                    (
                      ORG.ITEM_ID, ORG.ATTR_ID, ORG.SCOPE, ORG.VALUE, ORG.CHG_EMP, ORG.CHG_DATE
                    ) VALUES
                    (
                      TMP.ITEM_ID, TMP.ATTR_ID, TMP.SCOPE, TMP.WORK_VALUE, TMP.CHG_EMP, TMP.CHG_DATE
                    );
                   
            /* 4-2-2. ACT 데이터 'Y' */
            MERGE INTO TESTTB020 ORG
            USING (
                    SELECT    TO_CHAR(SYSDATE,'YYYYMMDD') PROC_DATE,
                            ITEM_ID,
                            REV_NO,
                            'A'            STATUS,
                            REGION,
                            MATR_TYPE,
                            FUNC_ROLE,
                            COMPANY,
                            PLANT,
                            'Y'            CONFIRM,
                            :NEW.ASSINGEE_ID   CHG_EMP
                    FROM     TESTTB020
                    WHERE    ITEM_ID    = :NEW.M00001
                    AND        REV_NO = :NEW.REVISION_ID    
                    AND        PLANT    = :NEW.M00069    
                    AND        STATUS    = 'C'
                   
                  ) TMP
              ON  (
                        ORG.ITEM_ID    = TMP.ITEM_ID
                  AND    ORG.REV_NO     = TMP.REV_NO
                  AND    ORG.STATUS    = TMP.STATUS
                  AND    ORG.REGION    = TMP.REGION
                  AND    ORG.MATR_TYPE    = TMP.MATR_TYPE
                  AND    ORG.COMPANY        = TMP.COMPANY
                  AND    ORG.PLANT        = TMP.PLANT
                  ) WHEN MATCHED THEN
                         UPDATE
                            SET    ORG.CONFIRM        = TMP.CONFIRM,
                                   ORG.EMP_NO         = TMP.CHG_EMP,
                                   ORG.CHG_DATE       = SYSDATE
                    WHEN NOT MATCHED THEN
                    INSERT
                    (
                      ORG.PROC_DATE, ORG.ITEM_ID, ORG.REV_NO, ORG.STATUS, ORG.REGION, ORG.MATR_TYPE, ORG.COMPANY, ORG.PLANT, ORG.CONFIRM, ORG.EMP_NO, ORG.CHG_DATE
                    ) VALUES
                    (
                        TMP.PROC_DATE, TMP.ITEM_ID, TMP.REV_NO, TMP.STATUS, TMP.REGION, TMP.MATR_TYPE, TMP.COMPANY, TMP.PLANT, TMP.CONFIRM, TMP.CHG_EMP, SYSDATE
                    );
         END IF;
         IF :NEW.IF_FLAG = 'S' AND (:NEW.REVISION_ID = '000' OR :NEW.REVISION_ID = 'MRP' OR  :NEW.REVISION_ID = 'EXT') THEN  
            MERGE INTO TESTTB010 ORG
            USING (
                    SELECT T1.ITEM_ID,
                            T1.ATTR_ID,
                            T1.SCOPE,
                            T1.VALUE WORK_VALUE,
                            T1.CHG_EMP,
                            T1.CHG_DATE
                    FROM TESTTB011 T1,
                            MDTAT010 T4
                    WHERE T1.ITEM_ID = :NEW.M00001
                    AND     T1.REV_NO = :NEW.REVISION_ID
                    AND  T1.ATTR_ID = T4.ID
                    AND  (T1.SCOPE = 'G' OR T1.SCOPE = 'C' OR T1.SCOPE = :NEW.REGION OR T1.SCOPE||'C' = (SELECT DISTINCT COMPANY FROM MDTCT050 WHERE PLANT = :NEW.M00069)||T4.CONTROL_LEVEL OR T1.SCOPE||'P' = :NEW.M00069||T4.CONTROL_LEVEL)     
                  ) TMP
              ON  (
                        ORG.ITEM_ID = TMP.ITEM_ID
                  --AND ORG.REV_NO  = TMP.REV_NO
                  AND ORG.ATTR_ID = TMP.ATTR_ID
                  AND ORG.SCOPE = TMP.SCOPE
                  ) WHEN MATCHED THEN
                         UPDATE
                            SET ORG.VALUE  = TMP.WORK_VALUE,
                                    ORG.CHG_EMP  = TMP.CHG_EMP,
                                    ORG.CHG_DATE         = TMP.CHG_DATE
                    WHEN NOT MATCHED THEN
                    INSERT
                    (
                      ORG.ITEM_ID, ORG.ATTR_ID, ORG.SCOPE, ORG.VALUE, ORG.CHG_EMP, ORG.CHG_DATE
                    ) VALUES
                    (
                      TMP.ITEM_ID, TMP.ATTR_ID, TMP.SCOPE, TMP.WORK_VALUE, TMP.CHG_EMP, TMP.CHG_DATE
                    ); 
         END IF;
                    
        END;

  •  

    Posted by 숏퐁숑
    , |

    최근에 달린 댓글

    글 보관함