매핑구문
- SQL 쿼리와 자바 객체 간의 매핑을 정의하는 부분
- XML 또는 Annotation을 사용하여 매핑
- DB와의 상호작용을 간편하게 처리
element(엘리먼트)
- XML 문서에서 사용되는 기본 단위
- 데이터를 구조화하고 표현하는 데 사용되는 태그
- XML에서는 엘리먼트가 데이터를 포함하는 구조를 형성하며, 각 엘리먼트는 시작 태그와 종료 태그로 구성
- XML은 첫 번째(first class) 엘리먼트만 가짐(=XML 파일의 root요소는 하나만 존재할 수 있음)
종류
- cache : 해당 네임스페이스를 위한 캐시 설정
- cache-ref : 다른 네임스페이스의 캐시 설정에 대한 참조
- resultMap : DB의 결과데이터를 객체에 로드하는 방법을 정의하는 엘리먼트
- sql : 다른 구문에서 재사용하기 위한 SQL 조각
- insert : 매핑된 insert 구문
- update : 매핑된 update 구문
- delete : 매핑된 delete 구문
- select : 매핑된 select 구문
select
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
- 구문의 이름 : selectPerson, 구문의 파라미터 : int type, 구문의 결과 데이터는 hashmap에 저장
- #{id} : Mybatis에게 PreparedStatement 파라미터를 만들도록 지시. Mybatis는 이 값을 PreparedStatement에 바인딩. 이 때, id는 매핑된 자바 객체에서 id라는 속성의 값을 가져와 SQL 쿼리에 삽입
select 엘리먼트 속성
<select
id="selectPerson"
parameterType="int"
parameterMap="deprecated"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
속성 |
설명 |
id |
SQL 쿼리를 찾기 위한 고유한 이름. 같은 네임스페이스 내에서 유일해야 함 |
parameterType |
SQL 쿼리에 전달할 파라미터의 데이터 타입 지정. 전체 클래스 이름이나 별칭 사용 가능 |
resultTypp |
SQL쿼리의 결과로 기대되는 데이터 타입 지정. 전체 클래스 이름이나 별칭을 사용하며, 컬렉션인 경우 결과를 포함하는 타입을 지정해야 함 |
resultMap |
외부에서 정의된 결과 맵을 참조 |
flushCache |
true로 설정하면 쿼리가 호출될 때마다 캐시가 지워짐. 기본값은 false |
useCache |
true로 설정하면 쿼리 결과가 2차 캐시에 저장. 기본값은 true |
timeout |
DB의 요청 결과를 기다리는 최대 시간. 기본값은 설정하지 않은 상태(드라이버의 기본 설정을 따르는 것) |
fetchSize |
한 번에 가져올 결과 수를 지정하는 값. 기본값은 설정하지 않은 상태 |
statementType |
STATEMENT,PREPARED,CALLABLE 중 하나를 선택하여 Mybatis가 사용할 쿼리 타입 지정. 기본값은 PREPARED |
resultSetType |
결과 집합의 유형 설정. 기본값은 설정하지 않은 상태 |
databaseId |
특정 DB에 대한 쿼리를 로드할 때 사용. DB ID가 있는 경우 해당 ID에 맞는 쿼리만 로드 |
resultOrdered |
내포된 결과를 조회하는 쿼리에서만 사용. 결과를 가져올 때 더 많은 메모리를 사용할 수 있음. 기본값은 false |
resultSets |
여러 결과 집합이 있는 경우 반환될 결과 집합의 이름 지정. 이름은 쉼표로 구분됨 |
affectData |
데이터의 삽입, 수정, 삭제 쿼리에서 결과를 반환할 때 이 속성을 true로 설정하여 트랜잭션이 올바르게 관리되도록 함. 기본값은 false |
- statementType : Mybatis가 SQL 쿼리를 실행할 때 어떤 방식으로 실행할지를 결정하는 설정
- STATEMENT : 매번 SQL 쿼리를 새로 만들고 실행. 매번 같은 쿼리를 실행할 때마다 쿼리를 다시 컴파일. 성능이 떨어질 수 있음.
- PREPARED(기본값) : 쿼리를 미리 준비해두고 필요한 값만 바꾸어 실행. SELECT * FROM USERS WHERE ID = ? 와 같이 미리 정의된 쿼리를 사용하고 ?자리에 값을 넣어서 실행. 성능이 좋고 SQL Injection공격 방지
- CALLABLE : DB에 미리 만들어 둔 저장 프로시저(여러 개의 SQL 쿼리를 묶어 놓은 것)를 호출할 때 사용. 복잡한 작업을 쉽게 처리할 수 있음
insert, update, delete
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">
<update
id="updateAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
insert, update, delete 엘리먼트 속성
속성 |
설명 |
id |
SQL쿼리르 찾기 위한 고유한 이름. 같은 네임스페이스 내에서 유일해야 함 |
parameterType |
SQL쿼리에 전달할 파라미터의 데이터 타입 지정. 전체 클래스 이름이나 별칭 사용 가능 |
flushCache |
true로 설정하면 호출될 때마다 캐시가 지워짐. 기본값은 false |
timeout |
DB의 요청 결과를 기다리는 최대 시간 설정. 기본값은 설정하지 않은 상태 |
statementType |
STATEMENT,PREPARED,CALLABLE 중 하나를 선택하여 Mybatis가 사용할 쿼리 타입 지정. 기본값은 PRREPARED |
useGeneratedKeys |
insert, update에만 적용. DB에서 생성한 키를 받도록 설정. 기본값은 false |
keyProperty |
생성된 키를 저장할 자바 객체의 속성 지정. 여러 개의 칼럼을 사용할 경우 속성 이름을 콤마로 구분하여 나열할 수 있음 |
keyColumn |
생성 키를 가진 테이블의 칼럼 이름을 지정. 키 칼럼이 첫 번째 칼럼이 아닐 경우에 필요 |
databaseId |
특정 DB에 대한 쿼리를 로드할 때 사용됨. DB ID가 있는 경우 해당 ID에 맞는 쿼리만 로드됨 |
selectKey 엘리먼트
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
selectKey 엘리먼트 속성
속성 |
설명 |
keyProperty |
selectKey의 결과를 저장할 자바 객체의 속성 이름. DB에서 가져온 키값을 어떤 변수에 저장할지를 설정 |
keyColumn |
DB에서 반환되는 결과의 칼럼 이름. 여러 칼럼을 사용할 경우 콤마로 구분하여 나열. 이 칼럼 이름이 keyProperty와 연결 |
resultType |
결과의 데이터 타입 지정. 이 속성은 선택적 |
order |
BEFORE 또는 AFTER를 설정할 수 있음. 기본값은 BEFORE |
statementType |
쿼리를 실행하는 방식 설정. STATEMENT, PREPARED, CALLABLE 중 하나로 지정 |
- BEFORE, AFTER
- BEFORE : 먼저 키 값을 조회한 후 이를 keyProperty에 저장하고 나서 INSERT 쿼리 실행(사용자를 추가할 때 먼저 사용자 ID를 미리 가져오고 그 ID를 사용하여 사용자 정보 저장)
- AFTER : 먼저 INSERT 쿼리를 실행한 후 그 다음에 키 값 조회(사용자를 추가한 후 그 ID를 데이터베이스에서 찾아서 사용)
SQL 엘리먼트
- 다른 구문에서 재사용가능한 SQL구문을 정의할 때 사용
- 로딩시점에 정적으로 파라미터처럼 사용할 수 있음
- 다른 프로퍼티값은 포함된 인스턴스에서 달라질 수 있음
sql 태그
- SQL 조각을 정의(자주 사용되는 SQL 구문을 미리 만들어 놓고 필요할 때마다 쉽게 재사용할 수 있도록 하는 것)할 때 사용
- 자주 사용하는 SQL 구문을 미리 만들어 놓고, 필요할 대마다 재사용할 수 있게 함
<sql id="userColumns"> ${alias}.id, ${alias}.username, ${alias}.password </sql>
- 사용자 관련 컬럼을 정의한 조각. alias는 다른 쿼리에서 사용될 때 실제 테이블 별칭으로 대체
<select id="selectUsers" resultType="map">
SELECT
<include refid="userColumns">
<property name="alias" value="u"/>
</include>
FROM users u
</select>
그러면 최종 쿼리는 다음과 같이 변환됨
SELECT u.id, u.username, u.password FROM users u
include 태그
- 정의된 SQL 조각을 다른 쿼리에서 포함할 때 사용
- 코드 중복을 줄이고, SQL 코드의 가독성을 높일 수 있음
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/></include>,
<include refid="userColumns"><property name="alias" value="t2"/></include>
from some_table t1
cross join some_table t2
</select>
- selectUsers쿼리에서 userColumns을 두 번 포함하는데 alias 속성을 통해 t1과 t2라는 별칭 지정
프로퍼티 사용
- 프로퍼티를 사용하면 SQL 조각에서 동적으로 값을 바꿀 수 있음
<sql id="sometable">
${prefix}Table
</sql>
Parameters
- 마이바티스에서 매우 중요한 엘리먼트
- 원시타입이나 간단한 데이터 타입은 프로퍼티를 가지지 않아 파라미터 전체가 값을 대체함
<select id="selectUsers" resultType="User">
select id, username, password
from users
where id = #{id}
</select>
- 여러 필드를 가진 사용자 정의 객체의 속성 사용
<insert id="insertUser" parameterType="User">
insert into users (id, username, password)
values (#{id}, #{username}, #{password})
</insert>
//사용 예
User user = new User();
user.setId(1);
user.setUsername("john_doe");
user.setPassword("securePassword");
userDao.insertUser(user); //MyBatis를 통해 insertUser 호출
Result Maps
- ResultSet에서 데이터를 가져올 때 작성되는 JDBC 코드를 대부분 줄여주는 역할 담당
- 모든 칼럼의 결과가 되는 간단한 구문에서는 HashMap에서 key 형태로 자동으로 매핑됨
<select id="selectUsers" resultType="map">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
TypeAliases
- 긴 클래스 이름 대신 짧은 별칭을 사용하여 쿼리를 작성
//XML 파일
<typeAlias type="com.someapp.model.User" alias="User"/>
// 쿼리
<select id="selectUsers" resultType="User">
SELECT id, username, hashedPassword
FROM some_table
WHERE id = #{id}
</select>