SQLMap.xml
다른 XML파일은 SQLMap.xml로 , 그 이름처럼 테이블간에 관계에 대한 정보를 가진다. 이 파일은 하나의 애플리케이션에서 여러개를 가질 수 있다. 이 파일은 SQL 문장들과 매핑되는 도메인 객체가 있는 것이 위치한다. 이 디스크립터는 입력으로 쓰일 문장과 SQL ResultSets로 매핑되는 결과에 대한 내용을 표기한다. 이 파일은 쿼리를 포함하기도 한다. 따라서 쿼리를 바꾸려면 애플리케이션의 자바 코드를 바꾸는 것이 아니라 XML을 바꾸어야 한다. 매핑은 데이터베이스와 상호작용할 실제 SQL문장을 사용하여 이루어진다. 이렇게 SQL을 사용하는 것은 개발자에게 매우 큰 융통성을 부여하며 SQL프로그래밍 경험을 가진 누구에게나 iBATIS를 쉽게 이해할 수 있게 해준다.
EMPLOYEE테이블에 대한 CRUD연산을 수행하는 SQL문을 정의한 SQLMap.xml파일이 아래 Listing 2에 있다.
Listing 2. SQLMap.xml for operations on EMPLOYEE
<sqlMap namespace="Employee">
<typeAlias alias="Employee" type="com.sample.Employee"/>
<resultMap id="EmpResult">
<result property="id" column="emp_id"/>
<result property="firstName" column="emp_firstname"/>
<result property="lastName" column="emp_lastname"/>
</resultMap>
<!-- Select all data from the table using the result map for Employee class.-->
<select id="selectAllEmps" resultMap="EmpResult">
select * from EMPLOYEE
</select>
<!-- Select the data from the table based on the id. -->
<select id="selectEmpById" parameterClass="int" resultClass="Employee">
<select emp_id as id,emp_firstname as firstName, emp_lastname as lastName from EMPLOYEE where emp_id= #id#
</select>
<!-- insert the data into the table -->
<insert id="insertEmp" parameterClass="Employee">
insert into EMPLOYEE (
emp_id,
emp_firstname,
emp_lastname)
values (
#id#, #firstName# , #lastName# )
</insert>
<!-- update the Employee record based on the id -->
<update id="updateEmp" parameterClass="Employee">
update EMPLOYEE set
emp_firstname = #firstName#,
emp_lastname = #lastName#
where
emp_id = #id#
</update>
<!-- delete the Employee record based on the given id -->
<delete id="deleteEmp" parameterClass="int">
delete from EMPLOYEE where emp_id = #id#
</delete>
</sqlMap>
Listing 2에서 typeAlias 태그는 타입에 대한 별칭으로 사용되어서 매번 경로까지 포함한 전체 클래스명을 타이핑하지 않아도 되도록 해준다. 이 태그는 쿼리로부터 반환되는 컬럼과 Employee클래스로 표현되는 클래스의 프로퍼티에 대한 매핑 정보를 가지는 resultMap 태그를 포함한다. 이 resultMap태크에 이어 쿼리들이 정의된다. SQLMap.xml은 여러개의 쿼리들을 포함한다. select, insert, update, delete 문장들은 각각의 태그안에 쓰여진다. 모든 문장은 id 어트리뷰트를 사용하여 이름이 지어진다.
Loading the descriptor files to your Java application
XML파일들간에 매핑작업과 전체적인 설정이 완료되면 SQLMapConfig.xml을 자바 애플리케이션에서 가져와 사용해야 한다. 첫단계는 앞서 작성했던 SQLMap.xml 설정파일을 로딩하는 것이다. 이를 위해 Listing 3.에 있는 iBATIS 프레임워크에 포함되어 있는 com.ibatis.common.resources.Resources 클래스를 사용할 것이다.
Listing 3. Loading SQLMap.xml
private static SqlMapClient sqlMapper;
...
try {
Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
} catch (IOException e) {
// Fail fast.
throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
}
}
SqlMapClient클래스는 SQLMaps와 함께 사용된다. 이는 select, insert, update등과 같은 문장들에 해당하는 액션들을 수행한다. SqlMapClient객체는 Thread safe하기때문에 한개의 객체만 사용해도 충분하다. 따라서 static 멤버로 선언하는 것이 적절하겠다. 이 객체는 하나의 SQLMapConfig.xml파일로부터 설정 정보를 읽어와 생성된다. iBATIS프래임워크는 SQLMapConfig.xml파일을 읽기 위한 Resources.getResourceAsReader() 유틸리티를 제공한다. 따라서 SQLMap클래스의 인스턴스를 사용하여 데이터베이스로부터 객체에 접근할 수 있다.(이번 경우에는 Employee객체)
EMPLOYEE테이블에 있는 연산을 호출하기 위해서 여러종류의 메소드가 있지만 그중에서도 queryForList(), queryForObject(), insert(), update(), queryForMap()과 같은 SQLMap에서 제공하는 메소드들이 제공된다. Listing4에 있는 queryForList()메소드는 Employee객체들의 리스트를 반환한다.
Listing 4. queryForList()
sqlMapper.queryForList("selectAllEmps");
쿼리의 결과로 한개의 로우를 가져오고자 할때는 queryForObject()를 사용하면 된다. 이 두가지 메소드 모두 파라미터로 쿼리문의 이름을 받는다.
이와 유사하게 Listing 5처럼 insert, update, delete연산을 수해할 수 있는 메소드들이 있다. 이 메소드들은 SQLMap.xml파일에 선언된 쿼리분의 이름과 파라미터로 Employee객체를 넘겨받는다.
Listing 5. Insert, update, and delete operations
sqlMapper.insert("insertEmp", emp);
sqlMapper.update("updateEmp", emp);
sqlMapper.delete("deleteEmp", id);
iBATIS에서는 이런 방식으로 SQL문장을 직접적으로 사용하여 자바객체를 저장하게 된다.
언제 iBATIS를 사용하는가
iBATIS는 SQL에 대한 모든 컨트롤을 하고자 할때 매우 적합하다. SQL쿼리들이 매우 잘 최적화되어있을때에도 유용하다. iBATIS는 애플리케이션과 데이터베이스간의 설계에 대한 모든 조작을 하고자 할때는 적합하지 않다. 그 이유는 애플리케이션과 데이터베이스간에 서로 잘 구조화되도록 설정이 바뀌어야하기 때문이다. 이러한 경우에 객체관계(object-relational)애플리케이션을 개발할 수 있으며 다른 ORM툴을 사용하는것이 더 올바른 선택일 것이다. iBATIS는 상대적으로 더 SQL중심적이기때문에, ORM툴들이 생성해내는 SQL에 반해 iBATIS는 SQL을 직접적으로 사용하게 된다. iBATIS는 관계 데이터베이스가 아닌 데이터베이스들을 사용할때에도 적절치 않다. 그러한 데이터베이스들은 트랜잭션이나 iBATIS가 사용하는 주요 기능들을 제공하지 않기 때문이다.
to be continue…
p.s>이제 좀 알고 싶은 내용이 나온다…-0-; 회사일이 바뻐서 진도를 못빼고 틈날때 바짝 하느라 번역질이 낮을거 같지만,,,
쿨하게 publish를 눌러본다.-_-;