본문 바로가기
Programming/SpringFramework

[Spring] MyBatis와 스프링 연동 & DB연동 테스트 예제

by prinha 2020. 8. 4.
728x90
반응형

 

MyBatis

개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다.

마이바티스는 JDBC로 처리하는 상당부분의 코드와 파라미터 설정및 결과 매핑을 대신해준다.

마이바티스는 데이터베이스 레코드에 원시타입과 Map 인터페이스,

그리고 자바 POJO 를 설정해서 매핑하기 위해 XML과 어노테이션을 사용할 수 있다.

 

- 자동으로 Connection close() 가능

- MyBatis 내부적으로 PreparedStatement 처리

- 리턴 타입을 지정하면, 자동으로 객체 생성및 ResutlSet 으로 처리

 

https://mybatis.org/mybatis-3/ko/index.html

 


1. pom.xml -> MyBatis 관련 maven 라이브러리 추가

 1) spring-jdbc/spring-tx : 스프링에서 데이터베이스 처리와 트랜잭션 처리(추가하지 않으면 에러발생됨)

 2) mybatis/mybatis-spring : MyBatis와 스프링 연동 라이브러리

 

 pom.xml 
자기가 사용하고자하는 라이브러리 plug-in 경로 작성

경로를 읽어들이고 local로 찾아감  (.m2 -> repository폴더) 
repository폴더에 파일들이 없으면 maven 사이트로 다시 찾아가서 폴더 안에 다시 다운로드

 

<!-- pom.xml -->

<org.springframework-version>5.1.5.RELEASE</org.springframework-version>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
     <version>${org.springframework-version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>

 

 

2. root-context.xml -> MVC 설정과 관련된 여러 처리를 담당

 - SqlSessionFactory는 데이터베이스와의 연결과 SQL의 실행에 대한 모든 것을 가진 가장 중요한 객체

 - bean : 주입을 하고자하는 기능, 목적

 -  ref -> bean중에 id 찾기 !!!!!

<?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">
	
	
	<!-- 이 코드만 있어도 DB연동 가능하긴 하나 sql 쿼리를 java파일에 써야한다 -->
	<!-- spring-jdbc 라이브러리 -->
	<!-- ★ 1.실제 클래스들에게 정보 제공 -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
		<property name="username" value="ora_user"/>
		<property name="password" value="1234"/>
	</bean>
	
	
	<!-- mybatis-spring 라이브러리 -->
	<!-- ★ 2.sqlSession 생성을 담당 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- setter 개념 -->
		<!-- ref="dataSource"
		<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">의 id가 옴
		실제 실행되는 것은 dataSource
		 -->
		<property name="dataSource" ref="dataSource" />
		<!-- sql 코드가 들어있는 xml 문서 -->
		<!-- /**/ -> mapper를 기준으로 하위 폴더 같은 레벨로 참조 , *Mapper.xml로 끝나는 파일 *에는 아무거나 상관없음 -->
		<property name="mapperLocations" value="classpath:mappers/**/*Mapper.xml" />
	</bean>
	
	
	<!-- ★ 3.실제 클래스에 주입 -->
	<!-- xml문서에서 sql구문을 읽어와서 실행을 담당하는 기능 제공 -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<!-- constructor-arg : 생성자 메소드 -->
		<!--   public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) ->  name -->
		<!--  ref="sqlSessionFactory" -> bean id="sqlSessionFactory" -->
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
	</bean>
	
</beans>

 

 

3. org.ex00.persistence -> DAO 역할의 패키지 생성

 

4. root-context.xml -> Class들을 bean으로 만들어주는 코드 작성

 - class들이 모두 bean 성격이 되야함

 - context:component-scan : 해당 패키지를 찾아가서 해당 클래스를 bean으로 생성 -> 스프링 컨테이너에 등록

 - 잊어버리는 경우가 많으니 미리 코드 작성해주기

<!-- <beans> 안에 작성 -->

<!-- 
스프링시스템이 시작하면서, org.ex00.sample 패키지에 Bean으로 생성할 클래스를 검색한 후에 생성
조건 : 해당 클래스에 bean으로 생성할 어노테이션이 있어야함

★ baen으로 생성할 클래스에 사용하는 어노테이션의 종류
@Component @Controller @Service @ Repository 등등 
-->
	
<!-- 해당 패키지를 찾아가서 어노테이션이 존재하면 해당 클래스를 bean으로 생성후 스프링 컨테이너에 등록 -->

<context:component-scan base-package="org.ex00.persistence"></context:component-scan>		

 

 

5. DAO 인터페이스 생성 -> 다형성

package org.ex00.persistence;

public interface BoardDAO {

	public String getTime();
}

 

 

6. DAO 인터페이스를 상속받는 클래스 생성 -> 다형성

 - 데이터 베이스와 연결된 작업을 하는 클래스

 - @Repository 또는 @Component 어노테이션 꼭 작성하기

package org.ex00.persistence;
import org.springframework.stereotype.Repository;

// 클래스가 DB관련 작업을 해주게하는 어노테이션
@Repository
public class BoardDAOImpl implements BoardDAO {

	@Override
	public String getTime() {
		return null;
	}
}

 

 

7. BoardMapper.xml -> sql 쿼리 작성

 - select sysdate from dual; --> sql 복사시 ; 제외

 - BoardMapper.xml은 BoardDAO의 제어를 받음

 - namespace와 id를 이용해 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="org.ex00.mapper.BoardMapper">

	<!-- id명은 BoardDAO 클래스의 method명과 똑같이 해주기 -->
	<select id="getTime" resultType="String">
		select sysdate from dual
	</select>
</mapper>

 

 

8. BoardDAOImpl implements BoardDAO -> 본격적인 DB관련 작업 코드 작성

 - Inject : 주입하는 대상

package org.ex00.persistence;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

// 클래스가 DB관련 작업을 해주게하는 어노테이션
@Repository
public class BoardDAOImpl implements BoardDAO {
	
	@Inject // 객체가 주입 대상이라는 것을 알려주는 어노테이션
	// root-context.xml에서 <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">의 부모
	// 결국 주입 대상은 SqlSessionTemplate의 부모 interface SqlSession  --> 다형성
	private SqlSession sqlSession;
	
	// BoardMapper.xml에서 mapper namespace 복사
	private static final String NS ="org.ex00.mapper.BoardMapper";
	
	
	// 혼란 방지를 위해 BoardMapper.xml의 mapper select id명과 메소드명 같게 해주기 
	@Override
	public String getTime() {
		
		// 쿼리문이 select문일때 두 가지 메소드 중 하나를 사용함!
		// 1) sqlSession.selectList(statement) -> 여러개 가져옴
		// 2) sqlSession.selectOne(statement) -> 하나 가져옴
		
		// mapper namespace + id (읽어오는)경로 써주기
		// org.ex00.mapper.BoardMapper.getTime
		return sqlSession.selectOne(NS+".getTime");
	}
}

 

 

9. 테스트 페이지 -> BoardDAOTest 클래스 생성

 - 경로 : src/text/java 에서 package org.ex00.persistence 안에 생성

 - 테스트 결과(console출력)  INFO : org.ex00.persistence.BoardDAOTest - 2020-08-05 22:49:47.0

package org.ex00.persistence;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.extern.log4j.Log4j;

// DI 의존성 주입 테스트

// Spring으로 실행되는 클래스 파일임을 의미함
@RunWith(SpringJUnit4ClassRunner.class)

// 구문을 분석해서 해당 패키지의 클래스를 Bean으로 생성, 스프링 컨테이너에 등록, DI(의존성 주입)로 사용
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")

@Log4j // Log for Java : 로그문의 출력을 다양한 대상으로 할 수 있도록 도와주는 도구
public class BoardDAOTest {
	
	// 클래스들이 bean으로 생성이되면 클래스이름의 맨 앞 스펠링이 소문자로!!
	// 다형성을 위해서 부모 interface를 써준다!!
	
	@Inject // 객체가 주입 대상이라는 것을 알려주는 어노테이션
	private BoardDAO dao;
	
	@Test
	public void getTime() {
		log.info(dao.getTime());
		// INFO : org.ex00.persistence.BoardDAOTest - 2020-08-05 11:12:15
	}
}

 

 

 

 

728x90
반응형