오늘은 Spring에서 사용하는 마이바티스를 정리해보겠습니다.
JDBC를 단순화하고, SQL을 XML에 정의하게 해준다. (마이바티스의 본질)
일반적으로 ‘마이바티스’라고 하면, 이 ‘코어 프레임워크’를 말한다.
자바로 데이터베이스 프로그래밍을 하면, 테이블 별로 SQL을 만들거나,
조회 결과를 담는 자바 모델 클래스 등을 만들어야 해서 시간이 많이 소요된다.
마이바티스 제너레이터는 테이블별로 SQL과 모델 클래스를 자동으로 만들어준다.
데이터베이스가 변경될 때, 그에 맞게 마이바티스 관련 파일을 변경해주는 도구이다.
운영중인 시스템의 데이터베이스를 변경하는 경우는 거의 없어서, 사용할 기회가 적다.

설정 정보를 가진 객체 생성 :
1) String resource = “mybatis-config.xml”; 구문으로 설정파일을 생성하고
2) InputStream inputStream; 구문으로 호출한다.
SqlSessionFactory 생성 :
1) SqlSessionFactoryBuilder를 먼저 생성하고
2) SqlSessionFactoryBuilder의 build메소드를 호출해 SqlSessionFactory를 생성한다.
→ SqlSessionFactory의 객체는 일반적으로 ‘하나만’ 생성한다.
⇒ SqlSessionFactory 객체생성은 JDBC에서의 ‘데이버테이스 연결 객체 생성’과 유사하다.
⇒ SqlSessionFactory 객체는 마이바티스 API를 사용하는 기본 객체이다.
⇒ SqlSessionFactory 객체가 마이바티스의 전반적인 정보를 제어하기 때문에 하나만
${ something }
JDBC의 PreparedStatement 의 ? 를 사용하지 않고 문자열 치환으로 처리하기 위한 표기법이다. #{ } 과 달리 변환과정이 생략되지만, SQL 인젝션 공격에 노출될 위험이 있다.
JDBC방식
마이바티스 방식
SQL을 별도의 XML에 작성한다.(자바코드가 아닌, 별도의 XML파일이나 어노테이션)
매핑 구문을 사용하기 위한 마이바티스 코드 생성
매핑된 구문을 사용해 데이터 CRUD (마이바티스 API를 사용)
→ 끝났으면 데이터베이스 자원 해제(SqlSession 객체 close)
객체를 생성할 때마다 트랜잭션을 시작한다.
마이바티스 설정 파일의 데이터 소스를 사용한다.
설정 값을 사용해 트랜잭션에 관련한 설정을 한다.
PreparedStatement는 재사용되지 않고 배치 형태로 처리하지 않는다.
→ 다양하게 오버로딩 되어있는 openSession 메소드들은 위의 특성을 변경하고 싶을 때,
매개변수를 넣어 사용한다.
데이터베이스에서 데이터를 조작하는 각종 작업 시,
특정 시점에 변경사항을 물리적으로 완전히 적용 혹은 취소하는 것이다.
보통 if구문으로 true일 시 commit // flase일 시rollback 사용(미리 정의)
마이바티스 사용 시, ‘트랜잭션 작업 시작’을 명시적으로 시작하는 메소드는 따로 없고,
openSession 메소드 호출로 SqlSession 생성 시에 시작될 뿐이다.
commit 이나 rollback 을 말하는 게 아님. 해당 작업은 해당 메소드를 호출해서 가능.
⇒ 스프링 미사용 시, SqlSession 클래스가 제공하는 commit과 rollback을 사용하고,
스프링 사용 시, 트랜잭션 제어는 마이바티스가 수행하지 않고 스프링에 위임된다.
→ 데이터 변동을 확인하기 위해, 대개 API가 반환한 값을 확인(0보다 크면 커밋, 0이나 음수면 롤백)한다.
ResultMap : 결과 매핑을 사용하기 위한 가장 상위 엘리먼트.
결과 매핑을 구분하기 위한 id속성과, 매핑 대상 클래스를 정의하는 type속성을 사용
id : 기본 키에 해당하는 값 설정
result : 기본 키가 아닌 나머지 칼럼에 대한 매핑
constructor : setter메소드나 리플렉션을 통하지 않고, 생성자를 통해 설정하는 경우 사용
association : 1:1 관계 처리 시
collection : 1:N(1:다수) 관계 처리 시
discriminator : 매핑 과정에서 조건을 지정해 값 설정 시
resultMap 엘리먼트에 딸려있는, 하위 엘리먼트
id : primary key 컬럼을 매핑하기 위한 태그. (성능 향상)
result : pk가 아닌 컬럼을 매핑하기 위한 태그.
constructor : 인스턴스화 되는 클래스의 생성자에 결과를 삽입하기 위해 사용.
→ 하위 엘리먼트로 , 엘리먼트가 있다. 각각 ‘키’ 와 ‘값’ 역할.
association : 복잡한 타입의 연관관계로 1:1 포함관계인 경우 사용한다.
collection : 복잡한 타입의 연관관계로 1:N 포함관계인 경우 사용한다.
discriminator
<select id=”selectCommentByPrimaryKey” parameterType=”long”
resultType=”Comment”>
SELECT
<include refid=”columns”>
FROM COMMENT
WHERE comment_no = # { commentNo }
⇒ 위와 같은 구문이 있을 때, ‘<include refid’= “columns”> 부분 같은 경우를 말함.
→ 정적인 내용 뿐만 아니라 동적 SQL도 넣을 수 있다.
마이바티스는 매퍼 인터페이스를 사용해 매핑구문과 결과 매핑 등을 정의할 수 있다.
매퍼 인터페이스의 ‘패키지명 인터페이스명’은 매퍼의 네임스페이스가 되고,
매퍼 인터페이스에 선언한 메소드는 매핑 구문 id가 된다.
매핑 구문에서 사용하는 SQL은 어노테이션을 사용해 정의한다.
매퍼 인터페이스가 사용하는 XML 엘리먼트
간단한 CRUD 를 처리하기 위한 매퍼 인터페이스
기존에 매퍼 XML에서 매핑 구문의 엘리먼트마다 SQL을 정의하던 것을
→ 어노테이션의 ‘파라미터’로 정의하면, 패키지명 인터페이스명을 네임스페이스로 사용하고
메소드명은 매핑 구문의 id, 메소드의 파라미터는 매핑 구문의 ‘파라미터 타입’이 된다.
⇒ 매퍼 XML을 구성하는 각 엘리먼트가 매퍼 인터페이스에서 무엇으로 바뀌는지
잘 숙지하면 매퍼 인터페이스 사용이 어렵지는 않을 것이다.(라고 책에 써있네요)
XML 결과 매핑과, 어노테이션 결과 매핑 사이에 몇가지 공통점이 있다.
XML 결과 매핑이 resultMap엘리먼트 + 하위에 id, result 엘리먼트를 쓰는 것처럼,
어노테이션 결과 매핑도 @Results 어노테이션과 + 하위에 @Result을 사용한다.
XML 결과 매핑의 id와 result 엘리먼트의 속성들은, 어노테이션 결과 매핑의 @Result
어노테이션에서도 동일한 속성을 가진다.
정리하면 :
그러나, XML 결과 매핑과 어노테이션 결과 매핑 사이에 차이점도 있다. (중요)
XML 결과 매핑의 타입은 type 속성을 사용해 정의했지만,
어노테이션 결과 매핑은 메소드 반환 타입을 사용한다.
어노테이션 결과 매핑은 다른 결과 매핑에서 재사용할 수 없다.
→ 따라서 XML 결과 매핑에서 제공하는 id 속성도 제공하지 않는다.
‘조건’에 의해 생성되는 ‘분기’에 대한 처리를 하기 위한 SQL 구조가 ‘동적 SQL’이다.
예를 들어, SELECT문으로 A라는 테이블에 대한 조회를 하고 싶은데,
등등 비슷한 구문이지만 조건절이나 조회할 컬럼 등 일부분만 다른 경우,
각각의 경우의 수에 대한 모든 쿼리문을 일일이 따로 작성해야 할까?
이럴 때, 쿼리문 자체에 조건문을 달아 경우에 맞게 ‘알아서 변동되는’ SQL이 동적 SQL이다.
단점으로는, 자바 코드를 사용해 동적SQL을 만드는 것 자체는 쉽지만, 분기처리가 많아질수록
가독성이 떨어지고, 오타 발생 확률이 높아져 유지보수가 어려워진다는 점이 있다.
마이바티스에서의 동적 SQL 사용법 : 3가지
XML에서 SQL을 위한 엘리먼트를 사용 시
마이바티스의 구문 빌더 API 사용 시
JDBC를 사용할 때처럼 자바 코드로 SQL을 만드는 문자열 처리
마이바티스를 사용하는 데이터 액세스 계층
‘조건’에 의해 생성되는 ‘분기’에 대한 처리를 하기 위한 SQL 구조가 ‘동적 SQL’이다.
예를 들어, SELECT문으로 A라는 테이블에 대한 조회를 하고 싶은데,
등등 비슷한 구문이지만 조건절이나 조회할 컬럼 등 일부분만 다른 경우,
각각의 경우의 수에 대한 모든 쿼리문을 일일이 따로 작성해야 할까?
이럴 때, 쿼리문 자체에 조건문을 달아 경우에 맞게 ‘알아서 변동되는’ SQL이 동적 SQL이다.
단점으로는, 자바 코드를 사용해 동적SQL을 만드는 것 자체는 쉽지만, 분기처리가 많아질수록
가독성이 떨어지고, 오타 발생 확률이 높아져 유지보수가 어려워진다는 점이 있다.
마이바티스에서의 동적 SQL 사용법 : 3가지
마이바티스를 사용하는 데이터 액세스 계층