마이바티스 프로그래밍 - 이동국 저
자바 애플리케이션에서는 테이블에 들어있는 데이터를 가져와서 사용하거나 조작을 하기 위해 그 데이터를 담는 객체를 만든다.
-> 자바 모델 클래스로 정의해서 사용
테이블별로 모델 클래스는 한 개씩 생성하며, 테이블의 칼럼들은 모델 클래스에서 필드로 만든다.
마이바티스에서 사용할 모델 클래스를 만들 때 주의 사항
Serializable
이어야 한다.데이터베이스는 전통적으로 칼럼의 이름을 만들 때 _
를 사용하지만, 자바에서는 CamelCase
를 주로 사용
#{commentNo}
자바 빈일 경우 변수명
또는 getter/setter
메소드에서 get/set
을 뺀 나머지 문자를 소문자로 시작해서 적어 주면 된다.
Map
객체일 때는 key
값을 적어 주면 설정해준다.
파라미터의 값이 한 개인 원시 타입의 경우 안에 아무 값이나 적어줘도 알아서 설정해준다.
마이바티스가 처리하는 과정에서 JDBC
코드와 같은 형태로 변환한다.
-> 결과적으로 JDBC
의 PreparedStatement
를 사용하게 되고 매핑 구문에 적용했던 마이바티스 파라미터 표기법은 PreparedStatement
의 ?
표현식으로 바뀐다.
${ }
표기법은 #{ }
표기법과는 달리 PreparedStatement
의 ?
표기법으로 변환하는 과정을 생략한다.
-> SQL Injection 공격에 노출될 수 있기 때문에 사용을 피해야 한다.
JDBC
코드처럼 자바 코드에 선언하지 않고 별도 XML
이나 애노테이션에 선언한 SQL
<!--1 start-->
<?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">
<!--1 end-->
<!--2 start-->
<mapper namespace="ldg.mybatis.repository.mapper.CommentMapper">
<!--2 end-->
<!--3 start-->
<select id="selectCommentByPrimaryKey" parameterType="long" resultType="ldg.mybatis.model.Comment">
SELECT
comment_no AS commentNo,
user_id AS userId,
comment_content AS commentContent,
reg_date AS regDate
FROM COMMENT
WHERE comment_no = #{commentNo}
</select>
<!--3 end-->
</mapper>
1️⃣ XML과 DOCTYPE 선언
첫 번째 줄 : 이 문서가 XML임을 나타낸다.
두 번째 줄부터 : 이 XML 문서가 사용하는 엘리먼트와 엘리먼트 간의 구조를 정의하는 DTD 선언
2️⃣ 매퍼 네임스페이스
매핑 구문들의 그룹
여러 개의 매퍼에서 매핑 구문 아이디가 겹치더라도 네임스페이스와 함께 매핑 구문 아이디를 사용하기 때문에 아이디가 겹치지 않게 잘 분류할 수 있다.
대개는 테이블명으로 네임스페이스를 정하고 매핑 구문 아이디는 SQL의 맥락에 따라 명명
3️⃣ 매핑 구문
id
: 자바 코드에서 SQL
을 선택할 때의 연결고리 역할
parameterType
: 조회 조건에서 사용할 값을 가진 파라미터의 타입
resultType
: 결과 데이터의 타입
public class CommentSessionRepository {
public Comment selectCommentByPrimaryKey(Long commentNo) {
// 1 start
SqlSession sqlSession = getSqlSessionFactory().openSession();
// 1 end
try {
// 2 start
return (Comment)sqlSession.selectOne("ldg.mybatis.repository.mapper.CommentMapper.selectCommentByPrimaryKey", commentNo);
// 2 end
} finally {
// 3 start
sqlSession.close();
// 3 end
}
}
}
1️⃣ 마이바티스 객체 생성
SqlSessionFactory
객체가 없다면 만들고, 있다면 기존 객체를 사용
마이바티스의 매핑 구문을 호출해서 사용하려면 SqlSession
객체가 필요하며, 각 데이터베이스 작업별로 SqlSession
객체를 사용하면 된다.
JDBC
코드에서 데이터베이스 연결 객체를 생성하는 것과 동일
2️⃣ 데이터 조회
selectOne
메소드에 첫 번째 파라미터로 매핑 구문을 지정하면 해당되는 SQL
을 실행하게 마이바티스가 처리네임스페이스.매핑 구분 ID
3️⃣ 데이터베이스 자원 해제
JDBC
와 달리 한꺼번에 데이터베이스 자원 객체를 해제한다.public class CommentSessionRepositoryTest {
public static void main(String[] args) {
Long commentNo = 1L;
CommentSessionRepository commentSessionRepository = new CommentSessionRepository();
Comment comment = commentSessionRepository.selectCommentByPrimaryKey(commentNo);
}
}
<mapper namespace="ldg.mybatis.repository.mapper.CommentMapper">
<insert id="insertComment" parameterType="ldg.mybatis.model.Comment">
INSERT INTO COMMENT(comment_no, user_id, comment_content, reg_date)
VALUES (#{commentNo}, #{userId}, #{commentContent}, #{regDate})
</insert>
</mapper>
resultType
속성을 지정하지 않은 이유는 PreparedStatement
객체가 제공하는 executeUpdate
메소드의 반환 값이 입력한 데이터 레코드 수이기 때문public Integer insertComment(Comment comment) {
SqlSession sqlSession = getSqlSessionFactory().openSession();
try {
int result = sqlSession.insert("ldg.mybatis.repository.mapper.CommentMapper.insertComment", comment);
if(result > 0) {
sqlSession.commit();
}
return result;
} finally {
sqlSession.close();
}
}