지난 1 회에서는 O/R매핑 및 O/R매핑 툴의 개요에 대해 설명하고, .NET전용의 대표적인 O/R매핑 툴인「NHibernate」를 소개했다.
O/R 매핑 툴을 사용하면, (C# 이나 VB.NET의) 오브젝트와 데이터베이스 상의 테이블을 매핑할 수 있다. 이것에
의해, 어플리케이션에서는 오브젝트의 속성에 액세스하기만 하면, 직감적으로 테이블상의 각 필드에 액세스할 수 있게 된다는 것이다.
지난 회의 서두에서 나타낸 것처럼, .NET 환경에서 이용 가능한 O/R 매핑 툴은 이미 얼마든지 제공되고 있다.
이번에는 NHibernate와 나란히 .NET 전용의 대표적인 O/R매핑 툴인「iBATIS.NET」에 대해 해설하면서, 실제로
그것을 이용한 ASP.NET의 웹 어플리케이션을 작성해 나간다.
iBATIS.NET
지난회에서 삺펴 본 것처럼, NHibernate는 SQL 퀘리를 자동 생성하기 때문에, 어플리케이션이 연구 최종 단계의 데이터베이스에 의존하기 어렵고, 원래 개발자가 SQL를 의식하지 않아도 되는 장점이 있다.
그러나 한편으로, SQL 퀘리에 의한 개발에 정통한 개발자에게 있어서는, 코드가 장황해져 버리기 쉽고, 섬세한 퍼포먼스
튜닝을 실시하기 어렵다는 단점이 있는 것도 사실이다. 만약 그러한 단점을 장점 이상으로 강하게 느끼고 있다면,
iBATIS.NET이라고 하는 선택 사항을 검토해도 좋을 것이다.
iBATIS.NET는 Apache Foundation 에서 제공되고 있는 오픈 소스의 O/R매핑 체제이다 *. 이 iBATIS.NET이 NHibernate와 크게 다른 것은 SQL 퀘리를 개발자 자신이 기술하는 타입의 O/R매핑 툴이라는 점이다.
iBATIS.NET에서는 SQL 퀘리를 외부 파일화 할 뿐이라서, NHibernate 등에 비해 간편하게 이용할 수
있고, 섬세한 퍼포먼스 튜닝도 실시하기 쉽고, 코드에서 SQL 퀘리를 분리하므로 코드를 보기 쉽다는 등의 장점이 있다. 물론,
SQL을 의식해야 하고, 사용하고 있는 SQL문에 따라서는 연구 최종 단계의 데이터베이스 제품에 의존할 가능성이 있는 등의
단점도 있긴 하지만, 양자의 장점/단점을 이해하고, 잘 구분하여 사용하길 바란다.
그러면 즉시, iBATIS.NET을 이용한 데이터베이스 액세스의 순서를 살펴 보자.
* iBATIS.NET
는 정확하게는 O/R매핑 기능을 주관하는「SQL Maps」과 DI(Dependency Injection) 기능을 주관하는「DAO
Framework」라고 하는 2가지의 기능으로 구성되는 체제(라이브러리)이다. 본문에서는 이 iBATIS.NET의 SQL
Maps 기능에 대해서만 언급하기로 하고, 이후에도 iBATIS.NET라고 했을 경우 SQL Maps를 가리킨다.
|
iBATIS.NET의 인스톨과 환경 설정
지난 회의 NHibernate와 같이 iBATIS.NET를 이용하려면, 미리 필요한 파일의 배치와 설정 파일의 정의를
끝마쳐 둘 필요가 있다. 구체적인 샘플 웹 어플리케이션을 살펴 보기 전에, 우선은 iBATIS.NET의 동작에 필요한 환경
설정을 완료해 두자.
[1]iBATIS.NET의 이용에 필요한 파일을 배치한다
iBATIS.NET를 이용하는데 있어서, 우선 이하의 사이트에서 필요한 파일을 다운로드해야 한다. 본문에서는 집필
시점에서의 최신 버젼인 1.2.1을 예로 채택하지만, iBATIS.NET는 매일매일 업데이트하고 있다. 그때그때의 최신판을
이용하길 바란다.
다운로드한 파일(본문의 예에서는 DataMapper-bin-1.2.1. zip)의 압축을 풀면, 몇 개의 파일이 전개될
것이다. 여기에서는 다운로드 파일에 포함되는 모든「.dll」파일을 어플리케이션 루트 아래의「bin」폴더에 카피한다.
또, providers.config를 어플리케이션 루트의 아래에 복사해 두자. providers.config는
iBATIS.NET가 이용하는 접속 프로바이더(각각의 데이터베이스 제품에 액세스하기 위한 기본적인 라이브러리 집단)의 설정을
정의하는 설정 파일이다.
[2]iBATIS.NET의 데이터베이스 접속 정보를 정의한다
iBATIS.NET에서는 우선 데이터베이스 접속 정보를 전용 설정 파일인 sqlMap.config로 선언해 두어야 한다. 이하는 본문의 샘플에서 이용하는 sqlMap.config의 기술 예이다.
또, sqlMap.config는 처음부터 스스로 기술해도 상관없지만, 다운로드 파일 안에도 템플릿으로서
SqlMap-sample.config가 포함되어 있다. 여기에는 최저 필요한 기술이 포함되어 있으므로, 이것을 편집하면 타입
미스도 적고, 효율적으로 작업을 진행할 수 있을 것이다.
<?xml version="1.0" encoding="UTF-8" ?>
<sqlMapConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="SqlMapConfig.xsd">
<providers resource="providers.config" />
<database>
<provider name="sqlServer1.1"/>
<dataSource name="sample" connectionString="Data Source=(local);User
ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=sample"
/>
</database>
<sqlMaps>
<sqlMap resource="./Book.xml" />
</sqlMaps>
</sqlMapConfig>
|
|
iBATIS.NET가 사용하는 데이터베이스 접속 정보의 설정 예(sqlMap.config) |
작성한 sqlMap.config는 다른「.aspx」파일과 같은 폴더(본문의 경우에는 어플리케이션 루트의 아래)에 저장할 것.
<providers>요소에는 접속 프로바이더의 정보를 정의한 설정 파일(providers.config)에의
패스를 지정한다. 앞에서 서술한 것처럼 providers.config는 iBATIS.NET가 대응하고 있는 접속 프로바이더를
기술한 설정 파일이다. providers.config는 미리 다운로드 파일에 포함되어 있으므로, 이것을 복사하기만 하면 되고,
스스로 편집할 필요는 없다.
이하에 providers.config로 정의되고 있는 주된 접속 프로바이더를 들어 보자.
접속 프로바이더명 |
데이터베이스 |
sqlServer1.0 |
SQL Server 7.0/2000(.NET Framework 1.0용) |
sqlServer1.1 |
SQL Server 7.0/2000(.NET Framework 1.1용) |
OleDb1.1 |
OLE DB(.NET Framework 1.1용) |
Odbc1.1 |
ODBC(.NET Framework 1.1용) |
oracle9.2 |
Oracle 9.2 |
oracle10.1 |
Oracle 10.1 |
oracleClient1.0 |
Oracle(Microsoft로부터 제공되고 있는 것) |
MySql |
MySQL |
SQLite3 |
SQLite 3.0 |
Firebird1.7 |
FireBird |
PostgreSql0.7 |
PostgreSQL |
iDb2.10 |
IBM DB2 |
|
iBATIS.NET가 대응하는 접속 프로바이더 |
다만, SQL Server, OLE DB, ODBC 이외의 데이터베이스를 이용하는 경우에는 별도의 데이터베이스 전용 접속 프로바이더(.NET 데이터 프로바이더)가 필요하게 되므로 주의하자.
실제의 접속 설정을 하는 것은 <database>요소의 역할이다. 사용하는 접속 프로바이더를 <provider>요소로, 접속 문자열을 <dataSource>요소로 각각 정의한다.
<sqlMaps>요소는 iBATIS.NET로 사용하는 매핑 파일에의 패스를 지정한다. 매핑 파일이란,
NHibernate의 해설에서도 소개했던 것처럼, 테이블상의 필드(열)와 클래스의 속성을 관련짓기 위한 정의 파일이다.
여기에서는 매핑 파일로서 Book.xml을 지정한다.
[3]매핑 파일을 정의한다
다음으로, sqlMap.config로 지정한 매핑 파일 Book.xml을 정의하고, books 테이블과 Book
클래스를 연관짓는다. 또, books 테이블, Book 클래스는 모두 지난회 NHibernate편에서 사용한 것을 그대로
이용하자.
<?xml version="1.0" encoding="UTF-8" ?>
<sqlMap namespace="Book"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="SqlMap.xsd">
<alias>
<typeAlias alias="Book" type="Com.Msn.Wings.Book, Book" />
</alias>
<resultMaps>
<resultMap id="booksResult" class="Book">
<result property="Isbn" column="isbn" />
<result property="Title" column="title" />
<result property="Price" column="price" />
<result property="Publish" column="publish" />
<result property="Published" column="published" />
</resultMap>
</resultMaps>
<statements>
<select id="getBooksInfo" resultMap="booksResult">
SELECT isbn,title,price,publish,published FROM books WHERE publish=#value#
</select>
……중략……
<insert id="setBookInfo" parameterClass="Book">
INSERT INTO books(isbn,title,price,publish,published) VALUES(#Isbn#,#Title#,#Price#,#Publish#,#Published#)
</insert>
</statements>
</sqlMap>
|
|
iBATIS.NET에 의한 매핑 파일의 기술 예(Book.xml)
|
클래스와 테이블을 관련짓는 것은 <resultMap>요소의 역할이다. id속성에 매핑명을, class
속성에 관련짓는 클래스명을 지정한다. 또한, 클래스명은 미리 <typeAlias>요소로 선언한
앨리어스(alias)(별칭)와 대응하고 있어야 한다.<typeAlias>요소의 구문은 이하와 같다.
<typeAlias alias="앨리어스(alias)명" type="클래스의 완전 수식명, 어셈블리명" />
<resultMap>요소 아래의 <result>요소는, 각각의 필드명과 속성을 관련 짓는다. property 속성에는 클래스의 속성명을, column 속성에는 대응하는 필드명을 각각 지정한다.
다음의 <statements>요소는 iBATIS.NET에서 발행하는 SQL 퀘리를 관리한다. <statements>요소의 아래에는 이하의 표에서 나타내 보이는 요소와 속성을 기술할 수 있다.
요소 |
속성 |
개요 |
<insert>
<update>
<delete> |
id |
SQL 퀘리명 |
parameterClass |
SQL 퀘리 내의 플레이스 홀더에 값을 설정하기 위한 클래스명 |
parameterMap |
SQL 퀘리 내의 플레이스 홀더에 값을 설정하기 위한 맵명 |
<select> |
id |
SQL 퀘리명 |
parameterClass |
SQL 퀘리 내의 플레이스 홀더에 값을 설정하기 위한 클래스명 |
parameterMap |
SQL 퀘리 내의 플레이스 홀더에 값을 설정하기 위한 맵명 |
resultClass |
취득한 결과 세트를 세트하는 클래스명 |
resultMap |
취득한 결과 세트를 세트하는 맵명 |
|
요소 아래에서 지정 가능한 주된 부하 요소와 속성 |
우선<select>요소는 그 이름에서도 쉽게 추측할 수 있듯이, SELECT 명령을 발행할 때 이용된다. INSERT/UPDATE/DELETE의 각 명령을 발행하는 경우에는 각각 대응하는 요소로 지정하면 된다.
id속성은 SQL 퀘리를 한꺼번에 특정하기 위한 논리명이다. 코드중에서 매핑 파일을 검색할 때의 키가 되는 정보이므로, 매핑 파일 내에서 반드시 한꺼번에 지정해야 한다.
resultMap 속성은 데이터베이스에서 취득한 결과 세트를 영속화 클래스(영속화 클래스에 대해서는 지난
1회의「[4]영속화 클래스를 정의한다」의 항목 을 참조)에 매핑하기 위한 맵명을 지정한다. 방금 전
<resultMap>요소로 지정한 id속성의 값을 세트할 것.
발행하는 SQL 퀘리 본체는 <select> (또는
<insert>/<update>/<delete>) 요소의 본체에 기술한다. 본문의 서두에서도
기술한 것처럼, iBATIS.NET에서는 NHibernate와 같은 O/R매핑 툴과는 달리, SQL 퀘리를 개발자가 명시적으로
기술해야 한다.
예를 들면 이하의 <select>요소는 프로그램 코드에서「getBooksInfo」라고 하는 ID로 식별되어 2행째에 있는 SELECT 명령을 데이터베이스에 대해 실행한다.
<select id="getBooksInfo" resultMap="booksResult">
SELECT isbn,title,price,publish,published FROM books WHERE publish=#value#
</select>
그리고 매핑 파일 내의 이하와 같은 <resultMap>요소의 기술에 따라서, 검색 결과의 각 필드 값이 Book 오브젝트의 각 속성에 대입된다는 것이다.
<resultMap id="booksResult" class="Book">
<result property="Isbn" column="isbn" />
<result property="Title" column="title" />
<result property="Price" column="price" />
<result property="Publish" column="publish" />
<result property="Published" column="published" />
</resultMap>
SQL 퀘리에는 「#value#」(무명 파라미터) 또는「#파라미터명#」(이름 파라미터)의 형식으로 플레이스 홀더를 설치하는 것이 가능하다.
무명 파라미터는 코드 안에서도 이름 등을 의식하지 않고, 직접 값을 세트 할 수 있는 것이 포인트이다. 퀘리 내에 플레이스 홀더가 1개밖에 없는 경우에는 무명 파라미터를 이용하는 것으로 코드를 간단하게 기술할 수 있다.
한편, 퀘리 내에 플레이스 홀더가 여러 개 존재하는 경우에는 이름 파라미터를 이용하면 된다. 자세한 것은 나중에
서술하겠지만, 이름 파라미터를 이용하는 것으로 parameterClass 속성으로 지정된 클래스와 같은 이름의 속성 값이
자동으로 세트된다. 즉, 위의 매핑 파일의 예(INSERT 명령)라면, Book.Isbn 속성의 값이 # Isbn#파라미터에,
Book.Title 속성의 값이 #Title#파라미터에 각각 자동으로 SQL 퀘리로 할당된다는 것이다.
|