MyBatis 도 하나의 독립된 프레임 워크이다.
MyBatis를 SQL Mapper FrameWork 라고 함.
파일명 : mybatis-config.xml
파일명은 개발자가 짓기 나름이지만, 통상적으로 위와 같이 만듦.
이 설정파일은, 반드시 classpath(build path)에 이 설정xml 파일이 있어야 함.
위 3개의 객체가 있어야, MyBatis를 통한 SQL 처리가 가능
MyBatis 설정파일에 대한, 입력스트림을 쉽게 얻을 수 있도록 도와주는 정적메소드 제공.
설정파일이 classpath 안에만 있다면,
그 위치를 정확히 알지 못해도 Resources 헬퍼클래스를 통해 입력스트림을 얻을 수 있다.
MyBatis에게 SQL 처리를 하라는 지시는,
1. sql 문자열을 준다고 되는게 아니다.
2. "SQL Mapper" 라고 하는 xml 파일을 이용해서 모든 sql문장을 저장/관리 함. (이용/실행)
3. "SQL Mapper" 는 하나의 xml이 아니라, n개의 xml파일로 구성 가능.
이때,
개발자가 MyBatis에게 수행시킬 sql문장이 들어있는 SQL Mapper가
정확히 어떤것을 사용해야 하는지 알려줘야 하는 문제가 발생.
이 문제 때문에, 아래 2가지를 같이 알려줘야 함
위 두가지 질문에 대한 답으로, 아래의 정보를 개발자가 제공해야 함.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Test1"> <!--****** namespace ******-->
<select id="getTime" resultType="java.lang.String"> <!--****** SQL id ******-->
SELECT sysdate FROM dual
</select>
</mapper>
위 mapper xml 파일은, MyBatis 설정파일 (mybatis-config.xml)에 등록해주어야 함.
<mappers>
<mapper resource="Test1Mapper.xml"/>
<mapper resource="Test2Mapper.xml"/>
...
</mappers>
즉,
- src/main/resources/<Mapper인터페이스의 패키지 생성>
- 1 폴더 아래에, <Mapper인터페이스명>.xml 파일 생성
- 2에서 생성한 xml파일의 namespace속성의 값을
..namespace=<Mapper인터페이스의 FQCN>으로 지정- 3에서 결정된 xml파일에, sql id를
mapper interface의 추상메소드 이름과 동일하게 지정
MyBatis의 sql mapper xml 파일에 등록된 sql 문자의 바인드변수(?) 가
2개 이상일 경우에는, SqlSession.selectXXX() 메소드 호출시에,
전달인자 값으로 아래의 2가지 경우가 가능하다
MyBatis 는 SQL Mapper XML 파일을 사용하지 않고,
MyBatis가 자체적으로 제공하는 어노테이션을 가지고 SQL처리가 가능하다.
(@Select, @Param)
mybatis가 proxy객체(proxy pattern)을 생성해서 구현해줌.
import org.apache.ibatis.annotations.Select;
public interface TimeMapper {
@Select("SELECT sysdate FROM dual") // 2nd. condition
public abstract String getNow(); // 1st. condition
} //end interface
이렇게 인터페이스를 사용할 경우, SQL 문장이 바뀌면 수정해주기가 매우 불편하므로
위 예시처럼 아주 간단한 문장일 경우에만 사용한다!!
위의 SQL Mapper XML 방식 + Interface 방식의 결합 사용
(MyBatis의 어노테이션은 사용하지 않음)
인터페이스와 SQL Mapper XML 파일과의 결합방식으로 SQL 문장을 처리
(1) 이 인터페이스가 소속된 패키지와 동일한 폴더구조를 resources 폴더에 만들어야 한다
(2) (1) 에서 생성된 마지막 폴더 안에, 이 인터페이스 이름과 동일한 SQL Mapper XML 파일을 생성
(3) (2) 에서 생성한 SQL Mapper XML의 파일의 namespace는 패키지 이름.인터페이스 이름과 동일하게 작성
(4) 수행시킬 SQL ID는, 이 추상메소드의 이름과 같게 작성
<![CDATA[]]>
태그<, > 등, 태그로 인식될 수 있는 문자들을, 있는 그대로의 문자로 사용하기 위해
<![CDATA[]]>
태그 내부에 작성한다.
특히 DQL문장의 경우 <, > 로 WHERE조건을 주는 경우가 있으므로
꼭 작성하자!
(mybatis 3.x 이상 버전에서는, " > "는 CDATA태그가 없어도 알아서 인식해주지만,
" < " 기호는 인식을 못한다)
MyBatis위에, SqlSessionFactoryBuilder를 만들고,
그 위에 SqlSessionFactory
추상적인 연결인 session 을 보고 함.
유저가 sql을 수행할때마다, session 을 새로 생성해야 함. (쓰레드마다 새로 생성)
따라서 지역변수로 사용.
Spring에서 사용하려면, mybatis-spring 라이브러리를 통해 연동처리 함.
MyBatis는 영속성 계층 (DAO역할)
Spring기반의 컴포넌트는 비즈니스 계층
스프링에서는 mybatis의 핵심객체를 우리가 직접 생성하는게 아니라,
SQLSessionFactory 객체를 beans container에 bean으로 등록
db connection 은 hiariDataSource가 제공하므로,
sqlSessionFactory는 이 커넥션을 이용해 만들기 위해
bean의 property로 지정 (root-context.xml)
root-context.xml에 <bean>
태그로 등록하면,
자동으로 setter 메소드로 등록됨.
INSERT INTO 테이블(컬럼1, 컬럼2, 컬럼3)
VALUE(#{컬럼1}, #{컬럼2}, #{컬럼3});
어떻게 MyBatis는 우리가 준 객체로부터 위의 바인드변수 값을 추출해내는가?
만약 우리가 준 객체가 자바빈즈 규약을 따르는 객체라면,
get{프로퍼티명}() 메소드 호출로 각 바인드 변수의 값을 얻어낸다.
없으면 오류 발생
만약 우리가 준 객체가 Map<K, V> 라면,
get{key이름}() 메소드 호출로 각 바인드변수의 값을 얻어낸다.
영속성 계층은 다른 계층은 신경쓰지 않는다.
DTO는 비즈니스계층에서 쓰인다. 영속성계층 호출할때는 DTO로 VO를 만들어서 집어넣는다.
각 계층은 독립성을 유지해야한다.
입력도 VO로 해야함.
selectKey 태그
좋은 내용 잘 보고 갑니다!