====== 개발 가이드 ====== ===== xDataSet 개요 ===== 이 장에서는 xFrame5 솔루션의 xDataSet 기능에 대한 기술적인 개요에 대하여 설명한다. 여기에서는 xDataSet 내부 구조에 대한 개념적인 부분을 설명하며, 이 장에서 기술하는 내용은 아래와 같다. * xDataSet 개요 * xDataSet 내부 아키텍처 * xDataSet 데이터 처리 흐름 아키텍처 ==== xDataSet 개요 ==== xDataSet 이란 xFrame5 솔루션에서 UI 및 서버 부분에서 데이터를 처리하기 위한 아키텍처이다. xDataSet 아키텍처는 UI 부분에서 처리하는 부분과 서버에서 처리하는 부분이 상호 연관적인 관계를 가지고 유기적으로 데이터를 처리하기 기반을 제공한다. 전체적인 아키텍처 구조는 아래의 그림과 같다. {{ .:development_guide:00.png?nolink |}} 위의 그림에서 데이터 흐름에 대한 설명은 아래와 같다. |< 100% 50px - >| ^ 구분 ^ 설명 ^ | 1 | 사용자 시스템에서 사용자가 트랜잭션을 발생시키기 위해서 트랜잭션 I/O 맵에 정의한 트랜잭션 ID 정보를 지정하여 트랜잭션 발생 함수를 호출한다. | | 2 | * xFrame-Viewer 내부의 xDataSet 컴포넌트가 트랜잭션 ID의 입력 맵 정보를 기준으로 데이터 셋에서 업무 서버 시스템으로 송신할 데이터를 조립한다. * 이때, 데이터 셋에 저장되어 있는 데이터뿐만 아니라, 화면의 메타 정보도 함께 조립하여 업무 서버 시스템으로 송신한다. | | 3 | 업무 서버 시스템의 업무 어플리케이션은 사용자 시스템으로부터 수신 받은 정보를 xdataset5.jar 라이브러리를 이용하여 필요한 데이터를 추출한다. | | 4 | 업무 서버 시스템의 업무 어플리케이션은 DBMS 와 연동하여 데이터 처리를 수행한다. | | 5 | 업무 서버 시스템의 업무 어플리케이션은 사용자 시스템으로 송신할 데이터를 xdataset5.jar 라이브러리를 이용하여 설정한다. | | 6 | 클라이언트로 송신될 데이터가 모두 설정된 이후에, 데이터를 사용자 시스템으로 송신하여, 업무 처리를 완료한다. | | 7 | 사용자 시스템에서는 업무 서버로부터 수신 받은 데이터를 xDataSet 컴포넌트에 의해서 자동 분석한다. | | 8 | 사용자 시스템의 xDataSet 시스템은 트랜잭션 ID 의 출력 맵 정보를 기준으로 데이터를 화면에 자동으로 표시한다. | ==== xDataSet 주요 기능 ==== xDataSet 의 주요 기능은 아래의 표와 같다. |< 100% 150px - >| ^ 구분 ^ 주요 기능 ^ | 사용자 시스템\\ (개발자 시스템) | * 글로벌 데이터 셋 기능 * 데이터 셋과 UI 컴포넌트간 1:N 데이터 바인딩 기능 * Query를 이용한 데이터 셋 자동 생성 기능 및 초기 데이터 설정 기능 * 데이터 셋을 이용한 화면 UI 컴포넌트 생성 및 자동 바인딩 기능 * 트랜잭션 맵 기능을 통한 데이터 셋 I/O 설정 기능 * First-Row 방식의 데이터 표시 기능 | | 업무 서버 시스템 | * 사용자 시스템의 UI로부터 수신된 데이터의 자동 분석 * 사용자 시스템으로 송신할 데이터에 대한 설정 기능 * 화면에 대한 Meta 정보 추출 기능 * 데이터 압축 송수신 기능 * First-Row 방식으로 데이터를 사용자 시스템의 UI로 송신하는 기능 | ==== xDataSet 내부 아키텍처 ==== 사용자 시스템에서 처리되는 xDataSet 내부 아키텍처는 아래와 같다. === 데이터 셋 구분 === 데이터 셋은 화면 데이터 셋과 글로벌 데이터 셋으로 구분되며, 각각의 특징은 아래와 표와 같다. |< 100% 150px ->| ^ 구분 ^ 주요 기능 ^ | 화면 데이터 셋 | *각각의 개별 화면에서 정의한 데이터 셋 *각각의 개별 화면에서만 접근 가능 | | 글로벌 데이터 셋 | *전역적으로 정의한 데이터 셋 *개별 화면에서 접근 가능 | === 송수신 데이터 구조 === 업무 서버로 송신되는 데이터에 대한 구조는 아래의 그림과 같다. {{ .:development_guide:01.png?nolink |}} 송수신 데이터의 각각의 항목에 대한 설명은 아래의 표와 같다. |< 100% 150px 50em>| ^ 구분 ^ 주요 기능 ^ | 트랜잭션 URL 파라미터 | *트랜잭션 맵에서 트랜잭션 URL 부분에 사용자가 지정한 파라미터 정보 *파라미터 정보는 GET 방식의 URL 지정 방식과 동일 *파라미터 이름 중 [XDATASET] 은 xFrame 내부에서 이용하므로 사용하면 안 됨 | | 화면 데이터 셋 | *각각의 개별 화면에서 지정한 데이터 셋 *트랜잭션 맵에서 지정한 데이터 셋의 데이터만 송수신 됨. | | 글로벌 데이터 셋 | *글로벌 데이터 셋으로 트랜잭션 맵에서 지정한 데이터 셋만 송수신 됨 | | 화면 메타 정보 | *화면 메타 정보는 아래의 데이터로 구성됨 *화면 속성의 [trancode]와 [transactionheader] 프로퍼티 정보 *화면 경로 및 이름 : 화면이 개발 툴 내에서 저장되어 있는 경로 및 이름 *사용자 시스템 IP 주소 : 실제 사용자 IP 주소 *트랜잭션 맵 ID : 사용자가 발생시킨 트랜잭션 ID | === 내부 데이터 셋 구조 === === xDataSet ID === 각각의 xDataSet은 고유의 ID를 가지며, 각각의 ID 는 다음과 같은 제약 사항이 있다. |< 100% 150px ->| ^ 구분 ^ 주요 기능 ^ | 화면 데이터 셋 | * 각각의 화면내의 xDataSet ID는 유일한 값을 가짐 * 화면 간 xDataSet의 이름은 동일해도 상관없음 * 화면내의 xDataSet ID는 글로벌 데이터 셋의 ID와 중복될 수 없음 | | 글로벌 데이터 셋 | * 전역적으로 유일한 값을 가짐 * 화면내의 xDataSet ID 값과 중복될 수 없음 | === xDataSet 컬럼 정의 === xDataSet 컬럼은 다음과 같은 속성을 가진 컬럼들로 구성된다 |< 100% 150px ->| ^ 구분 ^ 주요 기능 ^ | Column | * 데이터 셋의 컬럼 이름 * 단일 데이터 셋 내에서는 중복되지 않는 값을 가짐 | | Description | * 컬럼에 대한 부가 설명 * Query 실행기를 통해서 컬럼 정보를 설정할 경우에는, 테이블 정의 시에 지정한 컬럼의 [Comment] 값으로 설정됨 | | Length | * 컬럼에 들어갈 수 있는 데이터의 최대 길이 * Query 실행기를 통해서 컬럼 정보를 설정할 경우에는, 테이블 정의 시에 지정한 컬럼의 [Length] 값으로 설정됨 | === 데이터 셋 내부 구조 === xFrameViewer 에서 사용하는 xDataSet 은 아래 그림과 같이 데이터 셋의 데이터 이외에도 부가적인 정보를 가지고 있다. {{ .:development_guide:02.png?nolink |}} 위의 그림에서 예시한 데이터 셋 정보와 같이 데이터 셋 내부는 아래와 같이 데이터 부와 메타 데이터 부로 구성되며, 각 부분에 대한 설명은 아래와 같다. |< 100% 150px 160px ->| ^ 구분 |^ 주요 기능 ^ | xDataSet 데이터 부 || * xDataSet에 저장되어 있는 실제 데이터 * 데이터 셋의 컬럼별/로우별로 데이터가 저장됨 | | xDataSet\\ 메타 데이터 부 | ROW ID | * 데이터 셋 레코드의 로우 값 | | ::: | RECORD_STATUS | * 데이터 셋의 변경 상태 정보이며, 트랜잭션이 끝나면 모두 기본 상태의 NORMAL로 초기화됨 * NORMAL : 기존 데이터에서 값이 변경되지 않은 상태 (기본 상태) * UPDATE : 기존 데이터에서 값이 변경된 레코드 상태 * DELETE : 기존 데이터에서 값이 삭제된 레코드 상태 * INSERT : 기존 데이터에 새롭게 추가된 데이터 레코드 상태 | | ::: | RECORD_KEY | * 각 레코드를 구별하는 유일한 값 | | 상태 데이터 부 | UI 콘트롤 바인드 정보 | * 데이터 셋과 BIND된 UI 콘트롤 정보 리스트 * 하나 이상의 UI 콘트롤이 하나의 데이터 셋에 바인딩 될 수 있음 | | ::: | 전체 레코드 개수 | * 현재 데이터 셋에 저장되어 있는 전체 레코드 개수 | | ::: | CURRENT_ROW | * 현재 사용자가 보고 있는 레코드 위치 * 비어있는 데이터 셋 내에 처음으로 데이터가 저장되는 경우는 첫번 째 레코드 위치로 설정 * 데이터 셋이 그리드가 아닌 일반 텍스트성 콘트롤에 바인드 되어 있을 경우, UI 콘트롤에 표시되는 데이터는 CURRENT_ROW에 해당하는 데이터 셋의 정보가 표시됨 * 데이터 셋이 그리드 콘트롤에 바인딩 되어 있을 경우, 이 정보는 현재 UI 콘트롤에서 사용자가 선택한 ROW가 됨 | === 트랜잭션 맵 구조 === 트랜잭션 맵은 화면에서 업무 서버 시스템과의 통신 시 송수신 데이터에 사용되는 데이터 셋의 정보와 업무 서버 시스템의 URL 정보를 관리하는 맵이다. 트랜잭션 맵은 아래와 같은 정보를 정의한다. * 하나의 업무 화면에서는 하나 이상의 트랜잭션을 정의할 수 있으며, 각각의 트랜잭션은 트랜잭션 ID로구분된다. * 트랜잭션 ID별로 업무 서버 시스템의 URL 정보와 송수신 데이터 셋의 정보를 정의한다. * 송수신 대상 데이터 셋은 각각의 데이터 셋의 송수신 대상 컬럼을 정의한다. * 데이터 셋의 송수신 대상 레코드 기준을 정의한다. === 업무 서버 시스템 URL 정보 설정 방법 === 트랜잭션 ID 별로 업무 서버 시스템 URL 을 지정하는 방법은 아래와 같다. * 업무 서버 시스템 URL = BASE_URL + TRANSACTION_URL BASE_URL 은 업무 서버 시스템의 기본 URL 정보를 지정하는 값으로 트랜잭션마다 반복되는 정보를 미리 정의하고, 업무 시스템의 URL 정보를 일괄적으로 적용하기 위해서 사용된다. 설정방법은 [UI 개발 환경 설정] – [UI 환경 설정] 항목을 참고한다. === 데이터 셋의 송수신 대상 레코드 기준 정의 === 트랜잭션 ID 에 대한 송수신 대상 데이터 셋을 지정하는 방법은 아래의 표와 같이 입력/출력에 따라 구분되어 지정하며, 설정 값에 따라 데이터를 송수신하는 대상 데이터가 결정된다. |< 100% 100px 100px ->| ^ 구분 |^ 설명 ^ ^ 입출력 구분 ^ 설정 값 | | | 입력 | 공백 | 트랜잭션 발생시 업무 서버로 송신되지 않는 데이터 셋 | | ::: | ALL | 트랜잭션 발생시 업무 서버로 데이터 셋의 모든 데이터가 송신됨 | | ::: | UPDATE | 트랜잭션 발생시 업무 서버로 데이터 셋의 데이터 중에서 [RECORD STATUS] 상태가 “UPDATE, DELETE, INSERT”로 설정된 레코드만 송신됨 | | ::: | CHECKED | * 트랜잭션 발생시 업무 서버로 데이터 셋의 레코드 상태와 무관하게 그리드 콘트롤에서 Check된 레코드만 송신됨. * Check 방식을 사용하기 위해서는 데이터 셋과 링크된 그리드 콘트롤의[use_checkrow] 및 [multi_checkrow] 속성을 사용함. * 이때, 레코드의 상태는 변경 없음. | | 출력 | 공백 | * 트랜잭션 발생시 업무 서버로부터 수신처리 되지 않음. *업무 서버에서 해당 데이터 셋에 대한 데이터를 설정한 경우에도 데이터를 처리하지 않음 | | ::: | UPDATE | * 업무 서버로부터 수신된 데이터에서 데이터의 [RECORD KEY] 값을 기준으로 기존 데이터를 업데이트함 * 업무 서버로부터 수신된 데이터에서 [RECORD KEY] 값에 해당하는 데이터가 기존에 없는 경우에는 데이터 셋에 새롭게 추가됨 | | ::: | CLEAR | 기존에 저장된 데이터 셋의 모든 데이터를 삭제하고, 업무 서버로부터 수신된 데이터로 데이터 셋의 데이터를 설정함 | ==== xDataSet 데이터 처리 흐름 아키텍처 ==== ===일반 데이터 처리 흐름도 === xDataSet 의 데이터는 업무 서버 시스템과 사용자 UI 시스템간에 데이터를 아래의 그림과 같이 처리한다. {{ .:development_guide:03.png?nolink |}} |< 100% 50px ->| ^ 구분 ^ 설명 ^ | 1 | 사용자는 UI 이벤트(예: [조회] 버튼 클릭)를 발생시켜 업무 화면의 request_submit() 함수를 호출하여 정의된 트랜잭션 ID에 해당하는 트랜잭션을 발생시킴| | 2 | xFrame Viewer에서 트랜잭션 ID에 해당하는 업무 서버 시스템의 URL 정보와 트랜잭션 IO 맵 정보를 기준으로 업무 서버 시스템으로 송신할 데이터를 설정| | 3 | * 송신 데이터는 데이터 셋의 데이터 이외에도 부가적인 데이터가 송신됨 * 송신 데이터의 구조는 [xDataSet 내부아키텍처 - 송수신 데이터 구조] 참조 | | 4 | xdataset5.jar 라이브러리를 이용해서 입력 데이터를 얻어오고 비즈니스 업무 요건에 따라 처리| | 5 | xdataset5.jar 라이브러리를 이용해서 출력 데이터를 설정 | | 6 | xFrame Viewer에서 출력 데이터에 대한 수신 및 데이터 처리가 완료되면, 개발자가 정의한 트랜잭션 완료 시 처리할 비즈니스 로직을 처리하기 위해, 화면의 on_submit_complete() 함수를 호출| ===== xFrame5 개발 환경 설정 ===== 이 장에서는 xFrame5 개발 환경을 설정하는 방법을 설명한다. * xFrame5 서버 환경 설정 * xFrame5 UI 개발 환경 설정 ==== 서버 환경 설정 ==== === Eclipse 프로젝트 생성 === Eclipse 에서 다음과 같이 신규 프로젝트를 생성한다. (project name : xFrameApp) {{ .:development_guide:04.png?nolink |}} 새로 생성된 프로젝트의 [Properties]를 선택하여 Default Output Folder를 xFrameApp/WebContent/WEBINF/classes 로 선택한다. classes 폴더가 없을 경우에는 생성한 후 설정한다. {{ .:development_guide:33.png?nolink |}} === 톰캣 서버 설정 === [Window] – [Show View] – [Servers] 를 클릭한 후 [Servers] 탭에서 새로운 서버를 생성하고 앞서 생성한 프로젝트(xFrameApp)을 추가한다. 톰캣 서버의 버전은 해당 환경에 맞게 선택한다. {{ .:development_guide:6.png?nolink |}} {{ .:development_guide:7.png?nolink |}} === xFrame5 서버 환경 설정 === 다음 그림을 참고로 xFrame5의 서버 환경을 구성한다. {{ .:development_guide:08.png?nolink |}} * WebContent 디렉토리 하위에 project를 생성하고 그 하위에 sample 디렉토리를 생성한다. * C:\xFrame5 디렉토리에 xframe5.css, xframe5.html, xframe5.ico, xframe5.js 파일을 WebContent 디렉토리에 복사한다. * xFrame5 설치 디렉토리인 C:\xFrame5 디렉토리 하위에 xfs 디렉토리 중, css, ext, html, lib 폴더를 WebContent 디렉토리로 복사한다. * C:\xFrame5\jar\ 디렉토리에 xdataset5-xxxxxxxx.jar, mysql-connector-java-5.1.10-bin.jar 및 json-simple1.1.1.jar 파일을 WebContent\WEB-INF\lib\ 에 복사한다 * WebContent 하위에 jsp 폴더를 생성한다. === 프로젝트 디렉토리 구조 및 파일 개요 === 프로젝트 디렉토리 구조 및 내용은 아래와 같다. {{ .:development_guide:09.png?nolink |}} === XDATASET_BASEURL 설정 === xframe5.js 파일 내 XDATASET_BASEURL 을 http://127.0.0.1:8080/xFrameApp/jsp/ 로 설정한다. {{ .:development_guide:10.png?nolink |}} ==== UI 개발 환경 설정 ==== === xFrame5 프로젝트 생성 디렉토리 확인 === Eclipse 에서 생성한 xFrameApp 프로젝트 내 WebContent\project\sample 폴더를 선택 후 마우스 우클릭하여 [Properties] 를 선택하여 xFrame5@DevStudio 에서 프로젝트 루트 디렉토리로 사용할 디렉토리를 확인한다. {{ .:development_guide:11.png?nolink |}} === xFrame5@DevStudio 시작 === 바탕화면에 xFrame5@DevStudio 아이콘을 더블클릭하여 DevStudio 를 실행한다. 시작 화면에서 [File]탭 > [프로젝트 생성] 탭을 선택한 후 프로젝트 생성 경로를 [xFrame5 프로젝트 생성 디렉토리 확인]에서 확인한 디렉토리를 선택한다. 프로젝트 아이디와 이름을 [sample]로 입력한 후 생성 버튼을 클릭한다. {{ .:development_guide:12.png?nolink |}} === UI 환경 설정 === xFrame5@DevStudio [도구] 메뉴에서 [옵션]을 선택한다. {{ .:development_guide:13.png?nolink |}} [미리보기] 탭에서 HTML5 기본 URL 을 http://127.0.0.1:8080/xFrameApp/xframe5.html 로 입력한다. {{ .:development_guide:14.png?nolink |}} [기타] 탭에서 Transaction 탭 보기를 선택하고, 인코딩 방식을 UTF-8 로 선택한다. {{ .:development_guide:15.png?nolink |}} ===== xDataSet 활용 예제 ===== 이 장에서는 xDataSet 을 활용한 예제를 통해 xDataSet 의 사용법을 익힌다. * 예제 개요 * 예제 DB구성 * 예제 UI 개발 및 서버 개발 ==== 예제 개요 ==== xDataSet 을 이용한 직원정보조회 예제를 따라 해보며, xDataSet 의 기본적인 사용방법을 학습한다. 이 예제를 통해 트랜잭션과 데이터 셋의 사용방법도 함께 살펴보도록 한다. 본 예제는 다음과 같은 개발 환경을 전제로 기술한다. |< 100% 100px 100px ->| ^ 구분 ^ 소프트웨어 ^ 참고사이트 | | 개발 툴 | Eclipse | https://www.eclipse.org/ | | 웹 서버 | Tomcat | http://tomcat.apache.org/ | | DB | MySQL | https://www.mysql.com/ | 다음은 이 예제의 최종 실행화면이다. {{ .:development_guide:16.png?nolink |}} ==== 예제 DB 구성 ==== === 테이블 생성 === === 테이블 스키마 === 예제에서 활용될 스키마는 아래와 같으며, [테이블 생성 스크립트] 항목을 참고로 DB 에 해당 테이블을 생성한다. 테이블 명 : EMP_INFO |< 100% 100px 100px 60px 60px ->| ^ 컬럼 명 ^ 데이터 형식 ^ 길이 ^ Key ^ Comment ^ | emp_no | CHAR | 6 | PK | 직원번호 | | emp_no | VARCHAR | 20 | - | 직원이름 | | emp_age | INT | - | - | 직원나이 | | mail_addr | VARCHAR | 100 | - | 메일주소 | === 테이블 생성 스크립트 === 다음 스크립트를 참고로 예제 테이블을 생성한다. CREATE TABLE `emp_info` ( `emp_no` CHAR(6) NOT NULL COMMENT '직원번호', `emp_name` VARCHAR(20) DEFAULT NULL COMMENT '직원이름', `emp_age` INT(3) DEFAULT NULL COMMENT '직원나이', `mail_addr` VARCHAR(100) DEFAULT NULL COMMENT '메일주소', PRIMARY KEY (`emp_no`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; === 데이터 생성 === === 데이터 입력 스크립트 === 다음 스크립트를 참고로 예제 데이터를 입력한다. INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100111','김우섭',49,'wskim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100112','곽경환',42,'khkwak@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100115','전시교',50,'skjeon@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100117','김종인',47,'jikim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100118','유동균',40,'dkyou@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100124','임기조',35,'kjlim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100133','김용진',31,'yjkim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100212','김용상',36,'yskim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100215','김용완',54,'ywkim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100218','김지태',33,'jtkim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100221','홍성일',50,'sihong@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100223','김경환',43,'khkim@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100226','정학길',28,'hkjung@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100312','유승한',29,'shyou@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100319','방인홍',36,'ihbang@softbase.co.kr'); INSERT INTO `emp_info`(`emp_no`,`emp_name`,`emp_age`,`mail_addr`) VALUES ('100325','김종욱',37,'jwkim@softbase.co.kr'); commit; ==== UI 개발 ==== === UI 개발 환경 설정 === === xFrame5 프로젝트 생성 디렉토리 확인 === Eclipse에서 생성한 xFrameApp 프로젝트 내 WebContent\project\sample 폴더 선택 후 마우스 우클릭하여 [Properties] 를 선택하여 xFrame5@DevStudio 에서 프로젝트 루트 디렉토리로 사용할 디렉토리를 확인한다. {{ .:development_guide:05.png?nolink |}} === xFrame5@DevStudio 시작 === 바탕화면에 xFrame5@DevStudio 아이콘을 더블클릭하여 DevStudio 를 실행한다. 시작 화면에서 [File]탭 > [프로젝트 생성] 탭을 선택한 후 프로젝트 생성 경로를 [xFrame5 프로젝트 생성 디렉토리 확인]에서 확인한 디렉토리를 선택한다. 프로젝트 아이디와 이름을 [sample]로 입력한 후 생성 버튼을 클릭한다. {{ .:development_guide:12.png?nolink |}} === UI 환경 설정 === xFrame5@DevStudio [도구] 메뉴에서 [옵션]을 선택한다. {{ .:development_guide:13.png?nolink |}} [미리보기] 탭에서 HTML5 기본 URL 값으로 http://127.0.0.1:8080/xFrameApp/xframe5.html 을 입력한다. {{ .:development_guide:14.png?nolink |}} [기타] 탭에서 Transaction 탭 보기를 선택하고, 인코딩 방식을 UTF-8 로 선택한다. {{ .:development_guide:15.png?nolink |}} === UI 화면 구성 === === 새 화면 생성 === 프로젝트 창에서 프로젝트명을 선택 후 마우스 우 클릭하고 [디렉토리 생성] 메뉴를 선택한다. 디렉토리명은 “xDataset”으로 입력하여 디렉토리를 만든다. {{ .:development_guide:17.png?nolink |}} [화면] -> [새 화면] 메뉴를 선택하여 새 화면을 생성한다. 속성 창에서 title, width, height 을 설정한다. {{ .:development_guide:18.png?nolink |}} [화면] -> [저장] 메뉴를 선택하고 [xDataset] 디렉토리를 선택한 후 “Employee” 라는 이름으로 저장한다. {{ .:development_guide:19.png?nolink |}} === 데이터 셋 설정 === 화면 하단의 [Transaction] 탭의 [xDataSet] 탭을 선택한다. xDataSet List 에 xDataSet 을 추가한 후 아래와 같이 [xDataset ID]와 [Description]을 입력한다. {{ .:development_guide:20.png?nolink |}} === 데이터 셋 컬럼 정의 === 직원 정보를 저장할 DS_EMP_INFO 데이터 셋의 컬럼을 정의한다. DB 상에 존재하는 테이블을 가져와 데이터 셋의 컬럼을 정의하기 위해서 퀴리 실행기를 이용하여 [Column]을 정의한다. 다음 그림과 같이 xDataSet List 에서 [DS_EMP_INFO]를 클릭하고 [xDataSet Column]에 있는 [쿼리 실행기]를 클릭한다. {{ .:development_guide:21.png?nolink |}} [쿼리 실행기]가 실행 되면 [환경 설정] 버튼을 클릭하여 현재 사용하고 있는 데이터베이스 정보를 선택 및 입력한다. {{ .:development_guide:22.png?nolink |}} [쿼리 실행기]에서 “select * from emp_info” 질의문을 입력하고 [Run]버튼을 클릭하면 DB 의 테이블과 값들을 가져온 것을 확인 할 수 있다. [DS_EMP_INFO]의 [xDataSet Column]을 DB 와 동일하게 정의하기 위해서 [컬럼정보 가져오기] 버튼을 클릭한다. 참고로 [초기 데이터 가져오기] 버튼을 누르면 DB 에 저장된 데이터를 [Column Data]에 가져올 수도 있다. {{ .:development_guide:23.png?nolink |}} ==== 트랜잭션 설정 ==== 트랜잭션은 정보의 교환이나 데이터베이스 갱신 등 일련의 작업들에 대한 연속처리 단위를 의미한다. 화면에서 발생하는 트랜잭션을 정의하기 위하여 [Transaction]탭내에 [xTranMap] 탭을 선택한다. xTranMap Info 에 트랜잭션을 추가한 후 아래와 같이 [xTranMapID], [URL], [Comment] 값을 입력한다. {{ .:development_guide:24.png?nolink |}} [xTranMap I/O]를 설정한다. 입력 및 출력 항목에 대한 자세한 설명은 [xDataSet 내부 아키텍처 - 내부 데이터 셋 구조]를 참고한다. {{ .:development_guide:25.png?nolink |}} Transaction I/O 설정 |< 100% 150px 150px 150px - >| ^ xTranMapID ^ 출력데이터 ^ 데이터 구분 ^ 설명 ^ | TR_SELECT_EMP | DS_EMP_INFO | CLEAR | 직원 정보를 저장하고 있는 데이터 셋의 데이터를 삭제하고 업무 서버로부터 수신한 데이터를 이용해서 기존 데이터로 저장한다. | === UI 화면 개발 === 직원 정보 그리드는 xDataSet 과 연결 되어 서버에서 보내주는 데이터를 가져와 화면에 출력 한다. 다음 그림과 같이 xDataSet 목록 창에서 [DS_EMP_INFO]를 클릭하고 Drag & Drop 으로 그리드를 생성하고, 이벤트를 처리할 [조회] 버튼을 생성한다. {{ .:development_guide:26.png?nolink |}} 화면 구성 컨트롤 및 속성 |< 100% 50px 100px 100px - >| ^ 구분 ^컨트롤^ 속성 ^ 값 ^ | 1 | 버튼 | name | btnSelect | | ::: | ::: | text | 조회 | | 2 | 그리드 | name | grdEmpList | 그리드를 더블클릭 하면 [그리드 열 속성 등록 창]이 나온다. 각 열의 [데이터부]에 [link_data] 속성을 확인 해보면 xDataSet 과 연동되는 ID 의 Column 과 연결되어 있는 것을 알 수 있다. 예를 들어, [직원번호] 열의 [link_data]는 [DS_EMP_INFO]에 있는 [emp_no] Column 과 연결되어 있다. {{ .:development_guide:27.png?nolink |}} ==== 이벤트 처리 ==== === 트랜잭션 발생 버튼 이벤트 처리 === 사용자가 [조회] 버튼을 클릭할 경우, 업무 서버와의 데이터 트랜잭션이 발생한다. 이벤트를 처리할 함수를 생성하기 위해 [조회]버튼 속성에서 on_mouseup 항목을 클릭하여 다음과 같이 함수를 생성한다. {{ .:development_guide:28.png?nolink |}} 구현할 스크립트는 다음을 참고한다. function btnSelect_on_mouseup() { screen.requestsubmit("TR_SELECT_EMP", true); } 화면에 설정된 xTranMapID 를 기준으로 서버와 데이터를 송수신한다. 화면과 서버가 데이터를 주고받기 위해서는 screen 오브젝트의 requestsubmit API 를 사용하여 트랜잭션을발생시키며, screen.requestsubmit(strTranMapID, bProcAsync)의 파라미터는 다음 표를 참고 한다. |< 100% 150px - >| ^ 파라미터 ^ 설명 ^ | strTranMapID | * 트랜잭션을 발생시킬 트랜잭션 ID 를 지정한다. 트랜잭션 ID 는 [xTranMapInfo]에서 정의됨 * 트랜잭션 ID 는 업무 서버의 URL 정보와 송수신될 데이터 셋의 정보를 구별함 | | bProcAsync | 트랜잭션에 대한 통신 처리는 Sync 방식과 Async 방식으로 처리할 것을 지정함 * true : 트랜잭션이 Async 방식으로 처리되고, on_submitcomplete 함수가 콜백 처리됨 * false : 트랜잭션이 Sync 방식으로 처리되고, on_submitcomplete 함수가 콜백 처리되지 않음 | === Sync 방식과 Async 방식의 차이 === 트랜잭션 발생시에 처리 방식인 Sync 방식과 Async 방식의 차이는 아래의 표와 같다. |< 100% 200px - - >| ^ 항목 ^ Sync 방식 ^ Async 방식 ^ | 함수 리턴 시점 | 업무 서버로 데이터를 송신하고, 업무 서버로부터 데이터를 수신한 후, 수신 데이터에 대한 처리가 완료되면 함수 리턴 | 업무 서버로 데이터가 송신 완료되면 함수 리턴 | | 트랜잭션 완료 | requestsubmit 함수 호출이 리턴되면 거래 처리 완료 | screen_on_submitcomplete 함수가 호출되면 거래 처리 완료 | | 트랜잭션 처리 결과 정보 확인 | screen 오브젝트의 특정함수를 호출하여 결과 확인 | screen_on_submitcomplete 함수의 파라미터로 확인 | | 특징 | 트랜잭션이 완료되기 전에 사용자는 아무런 동작을 수행할 수 없음 | 트랜잭션을 완료되기 전에 사용자가 다른 동작이나 또 다른 트랜잭션을 발생시킬 수 있음 | === 트랜잭션 완료 버튼 이벤트 처리 === 트랜잭션이 완료되면 화면의 on_submitcomplete 함수가 xFrame-Viewer 에 의해서 자동으로 호출된다. 트랜잭션 완료 시에 자동으로 호출되는 screen_on_submitcomplete 함수의 역할은 트랜잭션의 정상 처리 유무에 대한 정보를 전달하기 위한 것이며, 함수의 파라미터 값은 아래의 표와 같다. |< 100% 150px - >| ^ 파라미터 ^ 설명 ^ | mapid | 처리 완료된 트랜잭션의 ID 로 툴에서 설정한 xTranMapID 값에 해당함 | | result | 처리 완료에 대한 정보로 ‘1’인 경우에는 정상이고, 그 이외의 경우에는 장애임 | | recv_userheader | 업무 서버 시스템에서 setUserHeader 함수를 통해서 지정한 값 | | recv_code | 업무 서버 시스템에서 setErrorMessage 함수를 통해서 지정한 코드 값 | | recv_msg | 업무 서버 시스템에서 setErrorMessage 함수를 통해서 지정한 메시지 값 | 본 예제에서는 트랜잭션이 완료되었을 경우, 아래의 그림과 같이 해당 정보를 개발콘솔에 표시하도록 개발할 것이다. 화면에서 on_submitcomplete 이벤트를 선택한다. {{ .:development_guide:29.png?nolink |}} 트랜잭션 완료 처리시에 호출되는 실제 함수 소스는 아래와 같다. function screen_on_submitcomplete(mapid, result, recv_userheader, recv_code, recv_msg) { // 처리 결과를 콘솔에 출력 factory.consoleprint("mapid = " + mapid); factory.consoleprint("result = " + result); factory.consoleprint("recv_userheader = " + recv_userheader); factory.consoleprint("recv_code = " + recv_code); factory.consoleprint("recv_msg = " + recv_msg); } ==== 서버 개발 ==== === 예제 구현 === === 직원 정보 조회 처리 개발 === WebContent\jsp 디렉토리 아래 SelectEmp.jsp를 생성하고, 다음 내용을 파일에 복사한다. 26~29 라인은 예제 테이블이 생성된 DB 환경에 알맞게 수정한다. <%@ page import="java.sql.DriverManager" %> <%@ page import="java.sql.Connection" %> <%@ page import="java.sql.PreparedStatement" %> <%@ page import="java.sql.ResultSet" %> <%@ page import="xdataset5.XDataSet5" %> <% Connection conn = null; // DB Connection Object PreparedStatement pstmt = null; // JDBC PreparedStatement Object ResultSet rs = null; // Query Result Set Object XDataSet5 xDataSet5 = null; // XFrame XDataSet Object try { // Clear out's buffer out.clearBuffer(); // Create XDataSet object xDataSet5 = new XDataSet5(request, response); System.out.println("ScreenNo : " + xDataSet5.getScreenNo()); System.out.println("IP : " + xDataSet5.getTerminalIpAddress()); System.out.println("Map ID : " + xDataSet5.getTransactionMapId()); System.out.println("User Header : " + xDataSet5.getUserHeader()); // For MySQL String driverClass = "com.mysql.jdbc.Driver"; String dbUrl = "jdbc:mysql://localhost:3306/xframe_data"; String dbUserId = "xframe"; String dbUserPasswd = "xframe"; // Load JDBC Driver and connect to database Class.forName(driverClass); conn = DriverManager.getConnection(dbUrl, dbUserId, dbUserPasswd); // Create a select query for EMP_INFO table String sQuery = "SELECT " + "emp_name, emp_no, emp_age, mail_addr " + "FROM " + "EMP_INFO " + "ORDER BY " + "emp_name"; // Creae a statement and execute a statement pstmt = conn.prepareStatement(sQuery); rs = pstmt.executeQuery(); // Loop a select result records for(int nRow = 0; rs.next(); nRow++) { // Get data from resultset String emp_name = rs.getString("emp_name"); if(emp_name == null) emp_name = ""; String emp_no = rs.getString("emp_no"); if(emp_no == null) emp_no = ""; String emp_age = rs.getString("emp_age"); if(emp_age == null) emp_age = ""; String mail_addr = rs.getString("mail_addr"); if(mail_addr == null) mail_addr = ""; // Set output data to XDataSet object xDataSet5.setData("DS_EMP_INFO", "emp_name", nRow, emp_name); xDataSet5.setData("DS_EMP_INFO", "emp_no", nRow, emp_no); xDataSet5.setData("DS_EMP_INFO", "emp_age", nRow, emp_age); xDataSet5.setData("DS_EMP_INFO", "mail_addr", nRow, mail_addr); } // Return data to XFrame xDataSet5.returnData(); } catch(Exception e) { try { if(xDataSet5 != null) { // Set error code and error message xDataSet5.setErrorMessage("XDATASET_ERROR", e.getMessage()); System.out.println(e.getMessage()); xDataSet5.returnData(); } } catch(Exception ex) { System.out.println("Exceptino Msg = " + ex.toString()); } } finally { // Release a database resources if(rs != null) { try { rs.close(); } catch(Exception ignore) {} } if(pstmt != null) { try { pstmt.close(); } catch(Exception ignore) {} } if(conn != null) { try { conn.close(); } catch(Exception ignore) {} } } %> === 예제 실행 === 구현된 [직원정보조회] 예제를 확인해 본다. === 톰캣 서버 시작 === 톰캣 시작 버튼을 클릭하여 서버를 시작한다. {{ .:development_guide:30.png?nolink |}} === 예제 확인 === [보기] – [미리보기(HTML5)]를 클릭하여 구현한 예제를 실행한다 {{ .:development_guide:31.png?nolink |}} [조회] 버튼을 클릭하여 직원정보가 정상적으로 조회되는 지 확인한다. {{ .:development_guide:32.png?nolink |}}