Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 팁&트릭
Delphi Programming Tip&Tricks
[279] "TSimpleDataSet"을 이용한 간단한 DB Middleware 예제
권익수 [freepascal] 4465 읽음    2011-12-05 15:32
Simple DB Middleware - TSimpleDataSet.zip 14.2KB Simple DB Middleware - TSimpleDataSet
DB를 이용한 프로그램을 개발할 경우 요즘은 2-Tier 보다는 보안 문제나 기타 여러가지 이유로 Multi-Tier로 많이 개발하게 됩니다. Multi-Tier로 개발하기 위해서는 DataSnap을 활용하는 방법도 있고, 다양한 델파이 컴퍼넌트나 고가의 Middleware를 사용하는 방법도 있습니다. 그런것도 좋지만 델파이 기본 컴퍼넌트를 활용해서 간단하게 DB Middleware를 한번 구현해 봤습니다.

개발 환경
. Delphi 2007 Enterprise / Indy10 / TSimpleDataSet

통신 규약
☞ 요청
. 구조: [Length] + [Command] + [Data]
구분형태길이설명
LengthInteger4 Bytes[Command]와 [Data]의 길이합
CommandChar1 ByteE: 쿼리실행(Insert, Delete, Update...)
O: Open(Select)
DataStringvariableSQL 구문

☞ 응답
. 구조: [Length] + [Command] + [Result]
구분형태길이설명
LengthInteger4 Bytes[Command]와 [Result]의 길이합
CommandChar1 Byte C: 접속응답
E: 쿼리실행(Insert, Delete, Update...)
O: Open(Select)
X: Error
ResultTIdBytesvariable 쿼리실행결과: 적용된 레코드 수
Open(Select)결과: 반환 Data
Error: Error Message

화면
. 서버 디자인 화면

. 서버 트레이메뉴

. 서버 로그 화면

. 클라이언트 디자인 화면

. 클라이언트 실행 화면 - Open Query

. 클라이언트 실행 화면 - Execute Query

서버 함수 설명
- procedure UP_AddLog(ALog: String);
오류나 요청/응답을 모니터링하기위한 로그 처리 함수로 간단하게 TMemo로 처리했지만, 실제 업무용으로 개발할 때는 File에 기록하는게 좋겠죠.
간단한 예제라서 Lock 처리도 안 했는데, 실제 사용할 프로그램에는 반드시 Lock 처리를 해주세요!

- procedure UP_SendData(var ACnxt: TIdContext; ACmd: Char; ACont: TIdBytes);
요청에 의해 처리된 결과를 클라이언트로 전송하기위한 함수 입니다.
데모라서 간단하게 만들었기때문에 암호화처리나 압축처리는 없는데 필요하다면 이곳에 추가하면 좋겠죠.

- procedure UP_ExecQuery(var ACnxt: TIdContext; ACmd: Char; var ACont: TIdBytes);
클라이언트에서 요청한 쿼리실행(Insert, Delete, Update...)구문을 처리하기 위한 함수입니다.
처리후 오류가 없다면 적용된 레코드 수를 요청한 클라이언트로 반환합니다.

- procedure UP_OpenQuery(var ACnxt: TIdContext; ACmd: Char; var ACont: TIdBytes);
Open요청된 SQL 구문을 받아서 조회된 결과를 클라이언트로 전송합니다.
복잡하게 구현하지않고 TClientDataSet의 SaveToStream을 활용해서 처리했고, 클라이언트 역시 TClientDataSet을 활용해서 반환된 결과를 조작없이 그대로 활용하였습니다.

- procedure UP_KillClient(AAll: Boolean = True);
비정상적으로 클라이언트가 죽을 경우 Indy Socket 특성상 서버에는 남아있게 됩니다. 그렇게 남겨진 컨넥션을 일정시간마다 돌면서 체크해서 죽이는 프로시져입니다.
그런 처리를 위해서 각 클라이언트마다 TSDDB라는 TObject에 요청시 최종요청시간을 갱신하고, 서버 구동시 Active 시킨 타이머에 의해 일정 시간마다 현재시간과 최종요청시간을 비교해서 일정시간이 경과한 클라이언트를 죽여버립니다.

기타 팁
. 2-Tier 개발시 처럼 쿼리컴퍼넌트에서 삭제/저장/추가시 자동으로 서버에 적용하기 위해서는 클라이언트 측의 TClientDataSet의 AfterDelete/AfterPost Envet에 서버로 쿼리실행 커맨드를 요청하는 처리를 추가하면 됩니다.
기본적인 처리를 구현한 Form을 상속받아서 코딩하면 좀더 쉽게 개발이 가능하겠죠?

. 일정 시간이 지나도록 요청이 없을 경우 자동으로 죽여버리는 처리때문에 클라이언트 접속이 강제 종료될 수 있는데, 아래와 같은 방법으로 접속을 유지시켜주면 강제 종료를 막을 수 있습니다.
방법 1. 일정 시간마다 의미없는 쿼리를 요청.
방법 2. 더미 처리를 위한 커맨드를 추가하고 일정 시간마다 더미 처리용 커맨드를 요청.

. 빈번한 요청이 없고 DB Server 성능이 떨어지는 환경이라면 요청후 DB 접속을 끊는 방법도 괜찮겠죠. 단, 요청이 빈번한 경우 DB에 접속하는 시간때문에 역효과가 날 수도 있습니다.

이용관 [bengi]   2011-12-09 02:24 X
귀중한 정보 감사합니다...^^

+ -

관련 글 리스트
279 "TSimpleDataSet"을 이용한 간단한 DB Middleware 예제 권익수 4465 2011/12/05
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.