실습 코드 참조
moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)
3.1절 라이브러리 내려받기 ( _075_BoardWeb_Spring_MVC_Mybatis_SqlSessionDaoSupport )
1. pom.xml
- 스프링과 MyBatis 연동에 필요한 라이브러리들 내려받기
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency>
<!-- Mybatis Spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.4</version>
</dependency>
2. 라이브러리 확인
3.2절 Mybatis 설정 파일 복사 및 수정
1. mappigs 폴더와 sql-map-config.xml 파일 복사 붙여넣기
- 스프링과 Mybatis를 연동하려면 Mybatis 메인 환경 설정 파일인 sql-map-config.xml과 SQL 명령어들이 저장되어 있는 Mapper 파일이 필요하다.
- 74번 프로젝트에서 작성한 mappigs 폴더와 sql-map-config.xml 파일을 복사해오기
2. sql-map-config.xml 소스 수정
- 데이터 소스 관련 설정은 삭제해준다.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- Alias 설정 -->
<typeAliases>
<typeAlias type="com.springbook.biz.board.BoardVO" alias="board"></typeAlias>
</typeAliases>
<!-- Sql Mapper 설정 -->
<mappers>
<mapper resource="mappings/board-mapping.xml" />
</mappers>
<!-- <mapper resource="mappings/user-mapping.xml" /> -->
</configuration>
3.3절 스프링 연동 설정
- 스프링과 Mybatis를 연동하려면 우선 스프링 설정 파일에 SqlSessionFactoryBean 클래스를 Bean 등록해야한다.
- 그래야 SqlSessionFactoryBean 객체로부터 DB 연동 구현에 사용할 SqlSession 객체를 얻을 수 있다.
- sqlSessionFactory가 SqlSession을 생산하기 위해서는 dataSource와 등록된 mapper 정보가 필요하다.
- 따라서 앞에 등록된 DataSource를 Setter 인젝션으로 참조하고, Sql Mapper가 등록된 sql-map-config.xml도 Setter 인젝션으로 설정해야한다.
- 그래야 bean 등록된 SqlSessionFactoryBean이 SqlSessionFactory 객체를 생성할 수 있다.
<!-- sessionFactory 객체 등록 -->
<!-- sqlSessionFactory가 SqlSession을 생산하기 위해서는 dataSource와 등록된 mapper정보가 필수 -->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:sql-map-config.xml"></property>
</bean>
3.4절 DAO 클래스 구현 - 방법1 ( _075_BoardWeb_Spring_MVC_Mybatis_SqlSessionDaoSupport )
1. BoardDAOMybatis.java
- 방법 1. SqlSessionDaoSupport 클래스를 상속하여 구현하기
- 스프링 설정 파일에 bean 등록된 SqlSessionFactoryBean 객체를 인자로 받아 부모인 SqlSessionDaoSupport에 setSqlSessionFactory() 메소드로 설정해준다.
- 이렇게 하면 SqlSessionDaoSupport 클래스로부터 상속된 getSqlSession() 메소드를 호출하여 SqlSession 객체를 리턴받을 수 있다.
package com.springbook.biz.board.impl;
import java.util.List;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
@Repository
public class BoardDAOMybatis extends SqlSessionDaoSupport {
@Autowired
//Spring 컨테이너가 자동으로 메소드를 호출해주고
//applicationContext파일에 등록된 SqlSessionFactoryBean 객체를 인자로 받아서 메소드를 실행
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
public void insertBoard(BoardVO vo) {
System.out.println("====> Mybatis로 insertBoard() 기능 처리");
getSqlSession().insert("BoardDAO.insertBoard");
}
public void updateBoard(BoardVO vo) {
System.out.println("====> Mybatis로 updateBoard() 기능 처리");
getSqlSession().update("BoardDAO.updateBoard");
}
public void deleteBoard(BoardVO vo) {
System.out.println("====> Mybatis로 deleteBoard() 기능 처리");
getSqlSession().delete("BoardDAO.deleteBoard");
}
public BoardVO getBoard(BoardVO vo) {
System.out.println("====> Mybatis로 getBoard() 기능 처리");
return (BoardVO)getSqlSession().selectOne("BoardDAO.getBoard", vo);
}
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("====> Mybatis로 getBoardList() 기능 처리");
return getSqlSession().selectList("BoardDAO.getBoardList", vo);
}
}
3.5절 DAO 클래스 구현 - 방법2 ( _076_BoardWeb_Spring_MVC_Mybatis_SqlSessionTemplate )
1. applicationContext.xml
- 두번째 방법 : SqlSessionTemplate 클래스를 bean 등록하여 사용한다.
- 스프링 설정 파일에서 SqlSessionTemplate 클래스를 SqlSessionFactoryBean 아래에 bean 등록한다.
- SqlSessionTemplate 클래스에는 Setter 메소드가 없어서 Setter 인젝션할 수 없으므로 생성자 메소드를 이용한 Constructor 주입으로 처리할 수 밖에 없다.
- 그러고 나서 DAO 클래스를 구현할 때, SqlSessionTemplate 객체를 @Autowired를 이용하여 의존성 주입 처리하면 SqlSessionTemplate 객체로 DB 연동 로직을 처리할 수 있다.
<!-- SqlSessionTemplate 객체 등록 -->
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sessionFactory"></constructor-arg>
</bean>
2. BoardDAOMybatis.java
- SqlSessionTemplate 객체를 @Autowired를 이용하여 의존성 주입 처리하여 SqlSessionTemplate 객체로 DB 연동 로직을 처리할 수 있도록 함
package com.springbook.biz.board.impl;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
@Repository
public class BoardDAOMybatis {
@Autowired
private SqlSessionTemplate mybatis;
public void insertBoard(BoardVO vo) {
System.out.println("====> Mybatis로 insertBoard() 기능 처리");
mybatis.insert("BoardDAO.insertBoard");
}
public void updateBoard(BoardVO vo) {
System.out.println("====> Mybatis로 updateBoard() 기능 처리");
mybatis.update("BoardDAO.updateBoard");
}
public void deleteBoard(BoardVO vo) {
System.out.println("====> Mybatis로 deleteBoard() 기능 처리");
mybatis.delete("BoardDAO.deleteBoard");
}
public BoardVO getBoard(BoardVO vo) {
System.out.println("====> Mybatis로 getBoard() 기능 처리");
return (BoardVO)mybatis.selectOne("BoardDAO.getBoard", vo);
}
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("====> Mybatis로 getBoardList() 기능 처리");
return mybatis.selectList("BoardDAO.getBoardList", vo);
}
}
3.6절 MyBatis 연동 테스트
1. BoardServiceImpl 클라이언트 프로그램 소스 수정
@Service("boardService")
public class BoardServiceImpl implements BoardService{
@Autowired
private BoardDAOMybatis boardDAO;
...
2. 웹 애플리케이션으로 테스트해보기
3.7절 MyBatis 연동 테스트 ( _077_BoardWeb_Spring_MVC_Mybatis_DynamicSQL )
1. Dynamic SQL 적용 전
-Mybatis는 SQL의 재사용성과 유연성을 향상하고자 Dynamic SQL을 지원한다.
- 우선 Dynamic SQL의 필요성을 확인하기 위해 Dynamic SQL을 적용하지 않고 검색 기능을 추가해보자
1) Board-mapping.xml
- 두 개의 쿼리가 필요함
<!-- Dynamic SQL 적용 전 -->
<select id="getBoardList_T" resultType="boardResult">
<![CDATA[
SELECT * FROM BOARD
WHERE TITLE LIKE CONCAT_WS('%', #{searchKeyword}, '%')
ORDER BY SEQ DESC
]]>
</select>
<select id="getBoardList_C" resultType="boardResult">
<![CDATA[
SELECT * FROM BOARD
WHERE CONTENT LIKE CONCAT_WS('%', #{searchKeyword}, '%')
ORDER BY SEQ DESC
]]>
</select>
2) BoardDAOMybatis.java
- 두 개의 쿼리를 등록했으면 이제 DAO 클래스 getBoardList() 메소드에 검색 조건에 따른 분기 처리 로직을 추가한다.
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("====> Mybatis로 getBoardList() 기능 처리");
if(vo.getSearchCondition().equals("TITLE")) {
return Mybatis.selectList("BoardDAO.getBoardList_T", vo);
} else if(vo.getSearchCondition().equals("CONTENT")) {
return Mybatis.selectList("BoardDAO.getBoardList_C", vo);
}
return null;
}
3) 단점
- 추가되는 검색 조건에 대해 반복적으로 작성해야한다.
2. Dynamic SQL 적용 후
- searchCondition 변숫값이 TITLE을 가지고 있으면 제목 검색에 해당하는 조건이 추가되고 CONTENT라는 값을 가지고 있으면 내용 검색에 해당하는 조건이 추가된다.
- 하나의 쿼리로 실행할 수 있다는 장점이 있다.
<!-- Dynamic SQL 적용 후 -->
<select id="getBoardList" resultMap="boardResult">
SELECT * FROM BOARD
WHERE 1=1
<if test="searchCondition == 'TITLE'">
AND TITLE LIKE CONCAT_WS('%', #{searchKeyword}, '%')
</if>
<if test="searchCondition == 'CONTENT'">
AND TITLE LIKE CONCAT_WS('%', #{searchKeyword}, '%')
</if>
<!-- <if test="title != null">
AND 1=1 해주는 이유 : 조건이 많아질 때를 고려해서 where절이 모두 지나가도록 해주려고
</if> -->
ORDER BY SEQ DESC
</select>
3. 실행 결과
댓글