자바에서 DB랑 연결할 때 쓰는 프레임워크.
SQL은 내가 직접 작성함 → SQL 제어 가능.
파라미터 바인딩/결과 매핑을 자동으로 해줌.
JPA보다 단순, SQL 친화적인 프로젝트에서 많이 씀.
<mapper namespace="com.example.UserMapper">
<select id="selectUser" parameterType="int" resultType="User">
SELECT *
FROM USERS
WHERE USER_ID = #{id}
</select>
<insert id="insertUser" parameterType="User">
INSERT INTO USERS (USER_ID, NAME, AGE)
VALUES (#{id}, #{name}, #{age})
</insert>
</mapper>
namespace → 연결할 자바 인터페이스.
id → 자바에서 호출할 메서드명.
#{} → 파라미터 바인딩 (SQL Injection 방지).
resultType → 결과 매핑할 자바 객체 타입.
User user = sqlSession.selectOne("com.example.UserMapper.selectUser", 1);
#{} vs ${}#{} : 안전 바인딩. → PreparedStatement의 ?로 치환됨.
${} : 문자열 치환. → SQL에 그대로 붙음. (주의 필요)
<!-- 안전한 방법 -->
SELECT * FROM USERS WHERE NAME = #{name}
<!-- 위험할 수 있음 -->
ORDER BY ${columnName}
${}는 보통 동적 컬럼명, 테이블명에만 씀.
마이바티스의 강점은 SQL을 조건부로 붙일 수 있다는 것임.
<if> 예시<select id="searchUsers" parameterType="map" resultType="User">
SELECT * FROM USERS
WHERE 1=1
<if test="name != null and name != ''">
AND NAME = #{name}
</if>
<if test="age != null">
AND AGE >= #{age}
</if>
</select>
<choose> 예시<select id="searchByRole" parameterType="string" resultType="User">
SELECT * FROM USERS
WHERE 1=1
<choose>
<when test="role == 'admin'">
AND ROLE = 'ADMIN'
</when>
<when test="role == 'user'">
AND ROLE = 'USER'
</when>
<otherwise>
AND ROLE IS NOT NULL
</otherwise>
</choose>
</select>
여러 조건 중 하나만 실행됨. (switch-case 같은 느낌)
SELECT NVL(NULL, '기본') FROM DUAL; -- 결과: '기본'
SELECT NVL('데이터', '기본') FROM DUAL; -- 결과: '데이터'
값이 null이면 지정한 기본값으로 바꿈.
SELECT DECODE(GENDER, 'M', '남자', 'F', '여자', '기타') AS GENDER_NAME
FROM USERS;
GENDER가 'M' → '남자'
GENDER가 'F' → '여자'
그 외 → '기타'
CASE + NVL + DECODE 조합CASE NVL(#{pcntTySeCd}, '2')
WHEN '1' THEN TO_CHAR(MEM_NO) || '|' || DECODE(TXTN_TY_SE_CD, '9','N','T')
ELSE TO_CHAR(MEM_NO)
END AS MEM_KEY
pcntTySeCd = '1' → MEM_NO|T / MEM_NO|N (과세/비과세 분리).
pcntTySeCd = '2' → MEM_NO (과세/비과세 합쳐서 중복 제거).
COUNT(DISTINCT MEM_KEY) AS MEM_CNT, -- 인원 수
COUNT(DISTINCT CTRT_NO) AS CNT -- 계약 수
MEM_CNT → 회원 수 (조건에 따라 중복 제거 기준 달라짐).
CNT → 계약 수.
회원번호 100, 과세/비과세 두 건 있음.
pcntTySeCd = 1 → MEM_CNT = 2
pcntTySeCd = 2 → MEM_CNT = 1
파라미터 이름 오타: pcntTySeCd vs pnntTySeCd.
COUNT(DISTINCT MEM_CNT) 같이 별칭을 DISTINCT에 넣는 것 → 문법 오류.
${} 남용 → SQL Injection 위험.
마이바티스는 SQL 직접 컨트롤 가능한 프레임워크.
오라클 함수(NVL, DECODE, CASE 등) 다 쓸 수 있음.
핵심은 #{} 바인딩, 동적 SQL 태그, 결과 매핑.
조건 분기에 따라 집계 로직을 바꿀 때, CASE NVL ... END 패턴이 유용.