Mybatis 연동하기
✒️ 2025-05-28 12:56 내용 수정
환경설정
- Mybatis를 STS에도 연동한다.
- Annotation 기반 설정 파일#프로젝트 설정에서 필요한 설정을 미리 준비한다.
- pom.xml 파일, config 패키지의 클래스들(RootContext, ServletContext, WebInitializer)
- web.xml, servlet-context.xml, root-context.xml 삭제
- src/main/resources에 context 패키지를 만들어 RootContext 파일을 옮긴다.
- RootContext 파일을 총 3개로 복사해서 각각의 이름을 Context_1_dataSource, Context_2_myBatis, Context_3_dao로 변경한다.
- Context_1_dataSource, Context_2_myBatis : 외부에서 온 라이브러리의 클래스들 객체로 만듦
- Context_3_dao : DB 접속 시 사용할 DAO 객체
- src/main/resources에 config 패키지를 만들어 WebInitializer 클래스를 옮긴다.
- src/main/resources에 mvc 패키지를 만들어 ServletContext 클래스를 옮긴다.
- WebInitializer에서 getRootConfigClasses() 메소드의 반환값을 Context_1_dataSource.class, Context_2_myBatis.class, Context_3_dao.class로 수정한다.
- oraclexe/app/oracle/product/11.2.0/server/jdbc/lib에서 ojdbc6.jar를 복사해서 apache-tomcat/lib에 붙여 넣는다.
- src/main/resources에 config.mybatis 패키지를 만들고, mybatis-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>
<settings>
<setting name="cacheEnabled" value="false" />
<setting name="useGeneratedKeys" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
</settings>
<!-- 별칭 등록 -->
<typeAliases>
<typeAlias type="package.className" alias="별칭"/>
</typeAliases>
<mappers>
<mapper resource="config/mybatis/mapper/mapperName.xml" />
</mappers>
</configuration>
- config.mybatis 패키지에 config.mybatis.mapper 패키지를 만들고, mapper 파일을 넣는다.
- 필요한 내용에 따라 수정해서 사용
<?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="namespace">
<select id="id" resultType="package.returnType">
select * from tableName
</select>
</mapper>
- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp 에 접속해서 1.4 버전을 선택하고, Maven 항목을 복사해서 pom.xml파일의 dependencies에 추가한다.
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
- Context_1_dataSource에 DataSource 객체를 추가한다.
@Bean
public DataSource ds() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.OracleDriver");
ds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
ds.setUsername("계정명");
ds.setPassword("비밀번호");
return ds;
}
- https://mvnrepository.com/artifact/org.mybatis/mybatis 에 접속해서 Mybatis 3.5.6 버전의 Maven을 복사해서 pom.xml 파일의 dependencies에 추가한다.
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring 에서 1.3.1 버전의 Maven을 복사해 pom.xml의 dependencies에 추가한다.
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
- https://mvnrepository.com/artifact/org.springframework/spring-jdbc 에서 spring과 동일한 버전의 jdbc를 찾아 Maven 항목을 복사해 pom.xml에 추가한다.
- 실습에서 사용한 spring은 5.1.20 버전이어서 해당 버전으로 받아 사용했다.
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
- Context_2_myBatis 클래스에서 DI를 통해 Datasource를 받고, SqlSessionFactory 객체를 Bean 객체로 생성한다.
- 생성자 주입으로 받기 위해 lombok에서
@RequiredArgsConstructor를 사용했다.
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
@Configuration
@RequiredArgsConstructor
public class Context_2_myBatis {
// 생성자 주입 - lombok의 @RequiredArgsConstructor로 지정
final DataSource ds;
@Bean
public SqlSessionFactory factoryBean() throws Exception{
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(ds);
// mapper를 알고있는 mybatis-config.xml 파일의 위치를 알려줘야 함
factoryBean.setConfigLocation(new ClassPathResource("config/mybatis/mybatis-config.xml"));
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionBean() throws Exception {
return new SqlSessionTemplate(factoryBean());
}
}
Mybatis Spring
- SqlSessionFactoryBean
- SqlSessionFactoryBean은 Spring의 FactoryBean 인터페이스를 구현한다.
- Spring이 SqlSessionFactoryBean 자체를 생성하는게 아닌 Factory에서 getObject() 메소드를 호출한 결과를 리턴한다.
- Spring은 어플리케이션 시작 지점에 SqlSessionFactory를 빌드하고, SqlSessionFactory라는 이름으로 저장한다.
- JSP에서 사용했던 Mybatis와의 차이점
- Mybatis에서는 SqlSession 객체를 생성하기 위해 SqlSessionFactory 객체를 사용한다.
- Mybatis Spring에서는 연동 모듈을 사용하면 SqlSessionFactory를 직접 사용할 필요가 없는데, Spring 트랜잭션 설정에 따라 자동으로 commit 또는 rollback을 수행하고 닫는 thread-safe SqlSession 객체가 Spring Bean에 주입되기 때문이다.
- SqlSessionTemplate 클래스는 SqlSession를 구현하고 코드에서 sqlSession을 대체하는 역할을 한다.
- SQL을 처리하는 Mybatis Method를 호출할 때 SqlSessionTemplate은 SqlSession이 현재 Spring transaction에 사용될 수 있도록 보장한다.
- SqlSessionTemplate은 필요한 시점에 Session을 닫고, commit하거나 rollback하는 것을 포함한 SqlSession의 라이프사이클을 관리한다.
DB에서 데이터 조회하기
- 데이터 조회는 Oracle의 HR 계정에 있는 Employees 테이블 내용을 사용한다.

- 연동을 마친 상태에서 src/main/resources에 dto 패키지를 만들고, EmployeesDTO 클래스를 만든다.
package dto;
import lombok.Data;
@Data
public class EmployeesDTO {
private int employee_id;
private String first_name;
private String last_name;
private String email;
private String phone_number;
private String job_id;
private int salary;
}
- src/main/resources에 dao 패키지를 만들고, EmployeesDAO 클래스를 만든다.
package dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import dto.EmployeesDTO;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class EmployeesDAO {
final SqlSession sqlSession;
// 전체 사원 조회
public List<EmployeesDTO> selectList() {
List<EmployeesDTO> list = sqlSession.selectList("employees.employees_list");
return list;
}
}
- Context_3_dao 클래스에 dao bean을 만든다.
package context;
import org.apache.ibatis.session.SqlSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import dao.EmployeesDAO;
@Configuration
public class Context_3_dao {
@Bean
public EmployeesDAO dao(SqlSession sqlSession) {
return new EmployeesDAO(sqlSession);
}
}
- mapper 파일에 SQL을 작성한다.
<?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="employees">
<select id="employees_list" resultType="employees">
select * from employees
</select>
</mapper>
- mybatis-config.xml 파일에서 mapper 이름과 기타 설정이 맞는지 확인하여 수정한다.
<?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>
<settings>
<setting name="cacheEnabled" value="false" />
<setting name="useGeneratedKeys" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
</settings>
<typeAliases>
<typeAlias type="dto.EmployeesDTO" alias="employees"/>
</typeAliases>
<mappers>
<mapper resource="config/mybatis/mapper/employees.xml" />
</mappers>
</configuration>
- src/main/java의 프로젝트 패키지에 EmployeesController 클래스를 만든다.
package com.nogroup.db;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import dao.EmployeesDAO;
import dto.EmployeesDTO;
import lombok.RequiredArgsConstructor;
@Controller
@RequiredArgsConstructor
public class EmployeesController {
public static final String VIEW_PATH = "/WEB-INF/views/";
final EmployeesDAO employees_dao;
@RequestMapping(value= {"/","list"})
public String list(Model model) {
List<EmployeesDTO> list = employees_dao.selectList();
model.addAttribute("list", list);
return VIEW_PATH+"employees_list.jsp";
}
}
- Controller 객체를 만들기 위해 ServletContext에 Bean을 추가한다.
package mvc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.nogroup.db.EmployeesController;
import dao.EmployeesDAO;
@Configuration
@EnableWebMvc
//@ComponentScan("com.nogroup.db") // 수동 Bean 생성을 위해 주석
public class ServletContext implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
//
// @Bean
// public InternalResourceViewResolver resolver() {
// InternalResourceViewResolver resolver = new InternalResourceViewResolver();
// resolver.setViewClass(JstlView.class);
// resolver.setPrefix("/WEB-INF/views/");
// resolver.setSuffix(".jsp");
// return resolver;
// }
@Bean
public EmployeesController empleController(EmployeesDAO employees_dao) {
return new EmployeesController(employees_dao);
}
}
- src/main/webapp/WEB-INF/views에 employees_list.jsp를 생성한다.
- 연동상에 에러가 뜬다면 코드를 다시 확인한다.
- Mapped Statements collection does not contain value for 에러가 뜬다면 자바킹's 에러 마이바티스 에러 Mapped Statedments collection does not contain value for 를 참고해서 원인을 확인해보자.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<th>사번</th>
<th>이름</th>
<th>성</th>
<th>이메일</th>
<th>전화번호</th>
<th>직무</th>
<th>급여</th>
</tr>
<c:forEach var="dto" items="${list}">
<tr>
<th>${dto.employee_id}</th>
<th>${dto.first_name}</th>
<th>${dto.last_name}</th>
<th>${dto.email}</th>
<th>${dto.phone_number}</th>
<th>${dto.job_id}</th>
<th>${dto.salary}</th>
</tr>
</c:forEach>
</table>
</body>
</html>