마치 심화편도 나올 것 같은 제목. 그러나 그냥 기초적인 부분을 이해해보려고 쓰는 것이라 기초편입니다.
새로운 것은 항상 재미있고 어렵구나.
MyBatis는 CRUD를 보다 편하게 하기 위해 xml로 구조화한 mapper설정 파일을 통해 JDBC를 구현한 영속성 프레임워크.
흠... JDBC로만 진행하다보면 좀 복잡하고 귀찮게 느껴지는 부분들(파라미터 설정, 결과 매핑 등)을 xml파일로 쉽게 세팅할 수 있도록 도와준다는 것 같다.
직접 사용해본 내손내쓴 후기를 말해보자면... 일단 sql문을 따로 분리해서 사용한다는 것이 굉장히 마음에 들었습니다.
예를 들자면, MyBatis를 사용하지 않았을 때는 아래의 코드처럼 메서드 중간에 sql문을 써서 사용해야 했다.
public NewsVO getNews(int aid) throws SQLException {
Connection conn = open();
NewsVO n = new NewsVO();
String sql = "SELECT aid, title, img, PARSEDATETIME(date, 'yyyy-MM-dd hh:mm:ss' AS cdate, content FROM news WHERE aid=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, aid);
ResultSet rs = pstmt.executeQuery();
rs.next();
.
.
.
}
근데 마이바티스를 사용하면 이렇게 sql문을 따로 mapper.xml 파일을 통해 관리할 수 있다
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="ch09.StudentMapper">
<select id="getStudents" resultType="ch09.Student">
select * from student
</select>
<insert id="insertStudent" parameterType="ch09.Student" statementType="PREPARED">
INSERT INTO student(username, univ, birth, email) VALUES(
#{username}, #{univ}, #{birth}, #{email}
)
</insert>
<delete id="deleteStudent" parameterType="ch09.Student" statementType="PREPARED">
DELETE FROM student
WHERE id=#{id}
</delete>
</mapper>
물론 메서드에 함께 작성하면 파일을 오가지 않아도 한 번에 확인 할 수 있겠지만, 개인적으로 이런 부분들은 파일을 분리하는 걸 좋아하는 편이라, 그리고 sql문을 확인하기 편해서 더 마음에 든다.

여기서 말하는 팩토리 빌더는 SqlSessionFactoryBuilder를 말한다.
우리가 Db에 접근해서 뭘 하려면
1. sql문을 쓸 수 있어야 하고,
2. sql문을 사용하려면 sql문을 실행하기 위한 메서드를 가지고 있는 SqlSession이 필요하고,
3. SqlSession을 만들기 위해 공장을 지어야 한다.
4. 근데 공장을 지으려면 땅이랑 땅에 접근할 권한(id, password)이 필요함
그럼 공장을 지어보자.
1. 공장을 지으려면 땅문서가 필요하다... 설정파일(ex. mybatis-config.xml => db url, id, password 등이 있음)을 작성한 뒤,
2. 땅문서 파일을 InputStream을 사용해서 읽어들인다.
3. SqlSessionFactoryBuilder를 통해 세션을 만드는 공장을 지어준다 뚝딱뚝딱.
우리의 공장 이름은 sqlSessionFactory입니다 참으로 직관적이죠
public class StudentDAO {
String resource = "ch09/mybatis-config.xml";
InputStream inputStream;
SqlSessionFactory sqlSessionFactory;
public StudentDAO() {
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
.
.
.
세션공장을 지었으면 세션을 만들어서 일을 시키면 됩니다.
그런데...
MyBatis는 mapper.xml에 있는 sql문을 이용해서 statement를 구현해주는데, 구현할 때 필요한 양식이 mapper interface 입니다. 라고 선생님이 설명해주셨는데 집에 와보니 갑자기 이 부분의 흐름이 정확히 이해가 안 됨...
내일 여쭤보고 다시 작성하기로...
public void insert(Student s) {
try (SqlSession session = sqlSessionFactory.openSession()) {
StudentMapper mapper = session.getMapper(StudentMapper.class);
mapper.insertStudent(s);
session.commit();
}
}
그리고 위의 코드들을 작성했던 StudentDAO의 DAO가 뭐냐하면...
- DAO (데이터 접근 객체, Data Access Object)

데이터베이스에 접근할 때 사용하는 객체.
사용자가 데이터를 요청했을 때, db에 접근하기 위해 커넥션 객체를 생성하게 된다 (ex_ Connection conn = 어쩌구 저쩌구...)
이 때, 다수의 서블렛에서 커넥션 객체를 생성할 경우 성능적으로도 좋지 못하고, 비즈니스 로직과 디비 로직을 분리해 db의 접근을 전담하는 객체를 만들어 사용하면 유지보수에도 편하니까... 그리고 db 로직을 캡슐화하여 데이터를 보호할 수도 있다.
한 줄 요약 - db에 접근하는 코드들을 여기다 몰아놨음.
벌써 열시다 이제 집에 가야함... 더 쓸 내용이 있다면 기초편 2로 돌아오겠습니다.
Velog가 불편해져서 다시 티스토리로 돌아왔는데 뭐 별다를 건 없는 것 같기도...