dbclient 계약 개념
주제 목차 · 다음: CRUD 계약 작성
이 문서의 결과: dbclient 계약(XML)의 구조와 파라미터 바인딩 원리를 설명한다.
왜 SQL을 XML로 감싸는가
SQL 문자열만 있으면 어떤 프로그램이 이 SQL을 실행할지, 어느 데이터베이스에 실행할지, 파라미터는 어떻게 받을지가 코드마다 제각각이 됩니다. dbclient는 이 정보를 계약(XML)으로 표준화해 어떤 SQL이든 같은 방식으로 실행·관리할 수 있게 합니다.
<?xml version="1.0" encoding="UTF-8"?>
<mapper xmlns="contract.xsd">
<header>
<application>HDS</application>
<project>BOD</project>
<transaction>BOD010</transaction>
<datasource>DB01</datasource>
<use>Y</use>
<desc>게시판 Board 테이블 조회</desc>
</header>
<commands>
<statement id="LD01" seq="0" use="Y" timeout="0" desc="분류·기간·제목 기준 게시글 조회">
<![CDATA[
SELECT B.ID, B.Category, B.Title, B.Author, B.DatePosted
FROM Board B
WHERE B.DatePosted BETWEEN @StartDate AND (@EndDate || ' 23:59:59')
AND CASE WHEN @Category = '' THEN @Category ELSE B.Category END = @Category
AND (@Title = '' OR B.Title LIKE '%' || @Title || '%')
ORDER BY B.ID DESC;
]]>
<param id="@Category" type="String" length="-1" value="" />
<param id="@Title" type="String" length="-1" value="" />
<param id="@StartDate" type="String" length="-1" value="" />
<param id="@EndDate" type="String" length="-1" value="" />
</statement>
</commands>
</mapper>
구조 요약
| 요소 | 역할 |
|---|---|
header | 프로그램·프로젝트·거래 ID, 사용할 데이터 원본(datasource) |
statement | SQL 하나, id가 기능 ID(예: LD01) |
param | SQL에서 쓰는 파라미터의 이름·타입·기본값 |
파일 이름(BOD010.xml)과 header의 transaction(BOD010)이 같아야 하며, 이는 02. 프로젝트 구조와 파일 작업에서 배운 항목 ID 규칙과 동일합니다.
파라미터 바인딩과 SQL 인젝션
@Category, @StartDate처럼 param으로 선언한 값은 SQL 문자열에 직접 이어붙이지 않고 매개변수로 바인딩합니다. 이 예제의 입력값은 SQL 구문이 아닌 데이터로 처리됩니다. 컬럼명·정렬 방향처럼 바인딩할 수 없는 구문을 동적으로 만들 때는 별도의 허용 목록 검증이 필요합니다.
자주 하는 오해
"WHERE 절의 CASE 문은 왜 필요 한가요? 그냥 @Category = @Category로 하면 안 되나요?"
조건값이 빈 문자열일 때 "전체 조회"를 의미하게 하려는 패턴입니다. CASE WHEN @Category = '' THEN @Category ELSE B.Category END = @Category는 @Category가 비어 있으면 항상 참이 되어 분류 조건 없이 전체를 조회하고, 값이 있으면 실제 컬럼과 비교합니다.
"datasource에 실제 연결 문자열을 적어야 하나요?"
아닙니다. datasource는 DB01처럼 서버에 등록된 데이터 원본의 ID일 뿐입니다. 실제 연결 정보는 서버 설정에서 관리하며, 계약 파일에는 절대 적지 않습니다.
CRUD 계약 작성에서 다른 SQL 계약을 추가합니다. 식별자의 정확한 의미는 식별자와 파일 경로를 참고하세요.