3-1. 0903_ MyBatis 더 알아보기
- Mapping 개념
xml을 이용한다.
- 가장 널리 사용되는 Java ORM Framework
- 소스코드에서 SQL Query 부분을 유연하게 관리할 수 있다는 특징

- 이클립스 장터에서 MyBatipse 플러그인을 선택하여 설치 (플러그인 이름 오타 아님,,)

- MyBatis 디펜던시 추가
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
- MyBatis Spring 디펜던시 추가
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
- mapper-emp.xml만들기
src폴더에서 마우스 우클릭 - new - other - mapper검색 - mybatis xml mapper 선택 후 이름 지정

- spring bean xml SqlSessionFactoryBean 정의 코드 context-spring-annotation.xml에 추가
<context-spring-annotation.xm 전체코드>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- DBCP 방식
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="hr" />
<property name="password" value="hr" />
</bean>
-->
<!-- HikariCP 방식 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="jdbcUrl">jdbc:oracle:thin:@localhost:1521:xe</prop>
<prop key="username">hr</prop>
<prop key="password">hr</prop>
</props>
</constructor-arg>
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="minimumIdle" value="5" />
<property name="maximumPoolSize" value="10" />
<property name="connectionTestQuery" value="select 1 from sys.dual" />
<property name="connectionTimeout" value="300000" />
</bean>
</constructor-arg>
</bean>
<!-- property name은 class마지막 부분 안에 있는 setter 함수 이름 -->
<!-- ref는 위쪽 bean id와 같아야 한다 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:mapper-*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<context:annotation-config></context:annotation-config>
<context:component-scan
base-package="myspringmybatis"></context:component-scan>
</beans>
* property name은 class마지막 부분 안에 있는 setter 함수 이름
* ref는 bean id와 같아야 한다.
* constructor-arg 는 생성자 매개변수
c.f. 클래스 vs 테이블
- 코딩은 클래스로
- DB는 테이블로 저장
- ORM (OR Mapping)
Mapping 파일
- SQL이나 OR 매핑을 XML파일로 기술한 파일
(=ORM, Object–Relational Mapping tool for the Java programming language)
- 하나의 애플리케이션에는 복수 개의 매핑 파일이 만들어 진다.
- NameSpace
* 매핑 파일의 Root Element(최상위)의 속성으로 지정한다.
* 매핑 파일에 기술된 SQL문장들을 그룹으로 묶는 역할을 한다.
* dtd (data type definition)를 보면 상위태그에 맞춰 어떤 하위 태그를 써야 하는지 보여줌

- SQL 문장의 기술
<mapper-emp.xml>
* select, update, insert, delete라는 이름의 태그를 사용한다.
<select id=“sql문장의ID(메소드 이름)” parameterType=“매개변수” resultType=“리턴타입”>
<!-- select 부서번호를 전달받아서 그 부서에 근무하는 사원목록을 리턴함
메소드 : List<EmpVO> getEmpListByDeptId(int deptId) -->
<select id="getEmpListByDeptId" parameterType="int" resultType="myspringmybatis.EmpVO"></select>
* id : SQL 문장의 식별자 역할을 수행한다.
* parameterTpye : 전달될 매개변수를 지정한다.
* resultType : 리턴타입을 지정한다.

<mapper-emp.xml 전체코드>
<?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="mapper-emp">
<!-- select부서번호를 전달받아서 그부서에 근무하는 사원목록을 리턴함
List<EmpVO> getEmpListByDeptId(int deptId) 이 부분에서
getEmpListByDeptId , List<EmpVO>, int deptId
<select id=“sql문장의ID(메소드 이름)” parameterType=“매개변수” resultType=“리턴타입”>-->
<select id="getEmpListByDeptId" parameterType="int" resultType="myspringmybatis.EmpVO">
select employee_id employeeId,
last_name lastName
from employees
where department_id = #{deptId}
</select>
</mapper>
- <bean id="sqlSessionFactory" 이 부분을 EmpDAO.java에 쓰는 방법
package myspringmybatis;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class EmpDAO {
// @Autowired
// DataSource dataSource;
@Autowired
SqlSessionTemplate sqlSession;
public List<EmpVO> getEmpListByDeptId(int deptId) throws Exception {
return sqlSession.selectList("getEmpListByDeptId", deptId);
// ArrayList<EmpVO> result = new ArrayList<EmpVO>();
//
//// Class.forName("oracle.jdbc.driver.OracleDriver");
//// Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
//
// Connection con = dataSource.getConnection();
// String sql = "select * from employees where department_id = ?";
// PreparedStatement stmt = con.prepareStatement(sql);
// stmt.setInt(1, deptId);
// ResultSet rs = stmt.executeQuery();
// while(rs.next()) {
// //EmpVO객체를 만들고 객체변수에 데이터베이스의 데이터로 설정하고
// EmpVO vo = new EmpVO();
// vo.employeeId = rs.getInt("employee_id");
// vo.lastName = rs.getString("last_name");
// result.add(vo);
//
// }
// return result;
}
}
↑ 기존에 오라클 커넥션을 위한 긴 코드가 전부 불필요하게 되고
단 몇 줄 만으로 간단하게 wiring이 됨
<EmpDAO.java 전체코드(다시 수정함)>
package myspringmybatis;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class EmpDAO {
@Autowired
SqlSession sqlSession;
public List<EmpVO> getEmpListByDeptId(int deptId) throws Exception {
return sqlSession.selectList("getEmpListByDeptId",deptId);
}
}
아직은 오류가 남
NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy
- sql 코드 수정
<select id="getEmpListByDeptId" parameterType="int" resultType="myspringmybatis.EmpVO">
select employee_id employeeId,
last_name lastName
from employees
where department_id = #{deptId}
</select>
- spring-jdbc 디펜던시 추가
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.20.RELEASE</version>
</dependency>
- 실행하면 나오는 콘솔 결과

- 한번에 import하는 방법 : ctrl + shift + O
- Alias(별칭)
- 노랑부분 : EmpVO 안에 있는 변수 이름이기 때문에 일치시켜줘야 한다.


- 실습하기(과제)
현재의 프로젝트에 추가합니다.
- 사용자로부터 사번을 입력받아서 그 사원의 (사번, 이름, 부서번호, 급여, 이메일)을 출력합니다.
- 0번을 입력하면 종료, 반복합니다.
1. EmpVO에 변수추가
2. EmpDAO에 메서드 추가
3. 매퍼 수정
4. EmpMain이라는 메인메서드가 있는 클래스 생성
테스트합니다.