1. MyBatis란?
- SQL Mapping Framework - Easy & Simple
SQL Mapping이라는 말은 Java 코드와 SQL을 매핑해준다는 뜻이다.
SQL을 별도 xml으로 분리해두고, Java 코드에서 xml에 있는 SQL을 간단한 코드로 사용할 수 있게 되어있어서 쉽고 심플.
- 자바 코드에서 SQL문을 분리해서 관리
- 매개변수 설정과 쿼리 결과를 읽어오는 코드를 제거
- 작성할 코드가 줄어서 생산성 향상 & 유지 보수 편리

SQL과 Java코드가 한 소스 파일에 같이 섞여 있다.
이걸 MyBatis를 이용하면 분리할 수 있다.
<?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="com.fastcampus.ch4.dao.UserMapper">
<insert id="insert" parameterType="com.fastcampus.ch4.domain.UserData">
INSERT INTO user_info
VALUES ( #{id}, #{pwd}, #{name}, #{email}, #{birth}, #{sns}, new());
</insert>
이런식으로 xml에 sql만 따로 태그를 이용해서 따로 분리하고, 자바 코드는 다음과 같이 간단해진다.
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private SqlSession session;
private static String namespace = "com.fastcampus.ch4.dao.UserMapper.";
@Override
public int insert(User user) {
return session.insert(namespace+"inserrt", user);
}
<실습>
- ch4 파일을 다운받아서 인텔리제이에서 open.
- 실습에 필요한 파일들 다운로드
- 인텔리제이 MySQL연결 후 테이블 생성

그리고 Maven Repository에서 다음 2개 코드를 복사한다.


Spring에서 MyBatis를 사용하려면 이 2개의 모듈이 필요하다.
2. SqlSessionFactoryBean과 SqlSession Template
- SqlSessionFactory : SqlSession을 생성해서 제공
- SqlSession - SQL 명령을 수행하는데 필요한 메서드 제공
=> 이 둘은 mybatis 모듈이 제공한다. 둘 다 인터페이스이다.
이 인터페이스를 구현한게 아래와 같다.
- SqlSessionFactoryBean : SqlSessionFactory를 Spring에서 사용하기 위한 빈
- SqlSessionTemplate : SQL 명령을 수행하는데 필요한 메서드 제공. thread-safe
=> 이 둘은 mybatis spring이 제공한다. 아래와 같이 빈으로 등록할 수 있다. (root-context.xml에 저장)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory"/>
</bean>
FactoryBean을 등록할 때 Mapper의 위치를 지정해줘야 한다.
Mapper.xml은 SQL문이 들어있는 xml문서이다. 이걸 종류별로 여러개를 만들기 때문에 앞에 *패턴이 붙어있다.
SqlSessionTemplate를 이용해서 Dao를 작성한다. 이 Dao가 여러 개 있을 수 있는데, SqlSessionTemplate을
공유할 수 있다. 그 이유는 멀티 쓰레드에 안전한 thread-safe이기 때문이다.
여러 쓰레드가 동시에 접근해도 SqlSessionTemplate이 알아서 관리해주기 때문에 안전한 것은 큰 장점이다.
3. SqlSession의 주요 메서드
| 메서드 | 설명 |
| int insert(String statement) int insert(String statement, Object parameter) |
insert문을 실행하고, insert된 행의 갯수를 반환 |
| int delete(String statement) int delete(String statement, Object parameter) |
delete문을 실행하고, delete된 행의 갯수를 반환 |
| int update(String statement) int update(String statement, Object parameter) |
update문을 실행하고, update된 행의 갯수를 반환 |
| T selectOne(String statement) T selectOne(String statement, Object parameter) |
하나의 행을 반환하는 select에 사용 parameter로 SQL에 binding될 값 제공 |
| List<E> selectList(String statement) List<E> selectList(String statement, Object parameter) |
여러 행을 반환하는 select에 사용 parameter로 SQL에 binding될 값 제공 |
| Map<K,V> selectMap(String statement, String keyCol) Map<K,V> selectMap(String statement, String keyCol, Object parameter) |
여러 행을 반환하는 select에 사용 keyCol에 Map의 key로 사용할 컬럼 지 |
- int : ~ DB에 영향을 준 row의 수
- selectOne : 한 행(row)
- selectList , selectMap : 여러개 행 (selectList를 더 많이 사용)
- Object parameter : insert into user_info value(?,?,?) -> 이 값들을 객체에 담아서 전달, User나 Map도 가능
- String statement : sql문 들어있는 xml의 이름 지정
4. Mapper XML의 작성
[boardMapper.xml]
<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
<select id="count" resultType="int">
SELECT count(*) FROM board
</select>
<delete id="deleteAll">
DELETE FROM board
</delete>
<delete id="delete" parameterType="map">
DELETE FROM board WHERE bno = #{bno} and writer = #{writer}
</delete>
<insert id="insert" parameterType="BoardDto">
INSERT INTO board
(title, content, writer)
VALUES
(#{title}, #{content}, #{writer})
</insert>
<select id="selectAll" resultType="BoardDto">
SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
FROM board
ORDER BY reg_date DESC, bno DESC
</select>
<sql id="selectFromBoard">
SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
FROM board
</sql>
<select id="select" parameterType="int" resultType="BoardDto">
<include refid="selectFromBoard"/>
WHERE bno = #{bno}
</select>
SQL문을 하나씩 만들어두고,
public class BoardDaoImpl implements BoardDao {
@Autowired
private SqlSession session;
private static String namespace = "com.fastcampus.ch4.dao.BoardMapper.";
public String getServerTime() throws Exception {
return session.selectOne(namespace+"new");
} // T selectOne(String statement)
public int count() throws Exception {
return session.selectOne(namespace+"count");
} // T selectOne(String statement)
public int insert(BoardDto dto) throws Exception {
return session.insert(namespace+"insert", dto);
} // int insert(String statement, Object parameter)
public BoardDto select(Integer bno) throws Exception {
return session.selectOne(namespace + "select", bno);
} // T selectOne(String statement, Object parameter)
호출할 때 이름을 준다.
5. <typeAliases>로 이름 짧게 하기 : http://mybatis.org/mybatis-3/configuration.html#typeAliases
mybatis – MyBatis 3 | Configuration
Configuration The MyBatis configuration contains settings and properties that have a dramatic effect on how MyBatis behaves. The high level structure of the document is as follows: configuration properties These are externalizable, substitutable properties
mybatis.org
<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
<select id="now" resultType="string">
SELECT now()
</select>
<select id="count" resultType="int">
SELECT count(*) FROM board
</select>
<insert id ="insert" parameterType="com.fastcampus.ch4.domain.BoardDto">
INSERT INTO board
(title, content, writer)
VALUES
(#{title}, #{content}, #{writer})
</insert>
<select id ="select" parameterType="int"
resultType="com.fastcampus.ch4.domain.BoardDto">
SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
FROM board
WHERE bno = #{bno}
</select>
너무 긴 부분을 별명을 통해 짧게 하고자 한다면 다음과 같이 하면 된다.
<typeAliases>
<typeAlias alias="BoardDto" type="com.fastcampus.ch4.domain.BoardDto"/>
</typeAliases>
BoardDto가 별명, com.fast~가 실제 이름이다.
별명은 대소문자를 구별하지 않고, 실제 이름은 대소문자를 구별한다.
<insert id ="insert" parameterType="BoardDto">
INSERT INTO board
(title, content, writer)
VALUES
(#{title}, #{content}, #{writer})
</insert>
<select id ="select" parameterType="int"
resultType="BoardDto">
SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
FROM board
WHERE bno = #{bno}
</select>'Spring' 카테고리의 다른 글
| ch4 03. 게시판 목록 만들기와 페이징 - TDD (1) (0) | 2023.03.17 |
|---|---|
| ch04 02. Mybatis로 DAO 작성하기 (0) | 2023.03.16 |
| ch3 21. 서비스 계층의 분리와 @Transactional(3) (0) | 2023.03.15 |
| ch3 20. 서비스 계층의 분리와 @Transactional(2) (0) | 2023.03.15 |
| ch3 19. 서비스 계층의 분리와 @Transactional(1) (0) | 2023.03.15 |