본문 바로가기
Java & Kotlin/Spring Data

[JSP] MyBatis

by heekng 2021. 3. 15.
반응형

[JSP] MyBatis

기존의 JSP에서 데이터베이스와의 통신을 하려면 JDBC를 이용하여 자바를 꼭 거쳐야 했다.

따라서 자바에서 불가피하게 SQL코드가 작성되었고, 자바와 SQL이 섞이다 보면 코드가 길어지고 섞여 유지보수와 분업이 쉽지 않아진다.

이러한 불편함을 해소하기 위해 myBatis를 이용한다.


myBatis 구조

myBatis는 기존의 JDBC방식과는 달리 sQL문을 XML파일에 작성함으로써 코드가 줄어들고, SQL문 수정이 편해진다.

또한 DBCP를 사용하여 커넥션을 여러 개 생성하기 때문에 JDBC만 사용하는 것 보다 작업 효율과 가독성이 좋아진다.

ibatis는 2.5버전이며 JDK4버전 이상에서 사용가능하다.

MyBatis는 3.0버전이며 JDK5버전 이상에서 지원한다.

ibatis와 MyBatis의 차이점은 몇 개의 문법 및 사용 용어(명칭) 변경 등이 있다.


MyBatis 작동순서

시작

1. 응용 프로그램이 SqlSessionFactoryBuilder를 통해 SqlSessionFactory를 빌드하도록 요청한다.

2. SqlSessionFactoryBuilder는 SqlSessionFactory를 생성하기 위한 MyBatis 구성파일을 읽는다.

3. SqlSessionFactoryBuilder는 MyBatis 구성 파일의 정의에 따라 SqlSessionFactory를 생성한다.

요청

4. 클라이언트가 응용 프로그램에 대한 프로세스(실행된 프로그램, 쓰레드풀에 요청)ㅇ을 요청한다.

5. 응용  프로그램은 SqlSessionFactoryBuilder를 사용하여 빌드된 SqlSessionFactory에서 SqlSession을 가져온다(메모리에 할당한다).

6. SqlSessionFactory는 SqlSession을 생성하고 이를 Application에 반환한다.

7. 응용 프로그램이 SqlSession에서 메퍼 인터페이스의 구현 개체를 가져온다.

8. 응용 프로그램이 매퍼 인터페이스의 메소드를 호출한다.

9. 매퍼 인터페이스의 구현 개체가 SqlSession의 메소드를 호출하고 SQL실행을 요청한다.

10. SqlSession은 매핑 파일에서 실행할 SQL을 가져와 SQL을 싱핼한다.


MyBatis 작동순서 예제

1. mybatis-x.x.x.jar, ojdbc[x].jar 두가지를 build path와 WEB-INF/lib에 추가

blog.mybatis.org/p/products.html

 

Products

A blog about the the MyBatis data mapper framework.

blog.mybatis.org

위의 MyBatis 3을 다운로드하고, ojdbc와 함께 build path한다.

2. SqlSessionFactoryBuilder을 통해 SqlSessionFactory를 빌드하도록 요청하고, SqlSessionFactoryBuilder는 MyBatis 구성 파일의 정의에 따라 SqlSessionFactory를 생성한다.

config.xml

3행의 Config를 꼭 작성한 후, DB의 설정에 맞춰 코드를 작성한다.

mapper를 작성하여 참조할 sql이 작성된 xml파일의 위치를 지정한다.

<?xml version="1.0" encoding="UTF-8"?>
<!-- mybaits의 config.xml임을 알린다. mybatis의 버전별로 다르기 때문에 꼭 pdf파일을 확인한 후 작성한다.-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!-- 연결한 DB의 정보를 작성한다. -->
<configuration>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="oracle.jdbc.OracleDriver"/>
				<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
				<property name="username" value="hr"/>
				<property name="password" value="hr"/>
			</dataSource>				
		</environment>
	</environments>
	
	<!-- 참조할 sql이 작성될 xml파일의 위치를 지정해준다. -->
	<mappers>
		<mapper resource="mybatis/sql/blog.xml"/>
	</mappers>
</configuration>

SqlMapConfig.java

SqlSessionFactory를 생성하는 과정

package mybatis.config;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlMapConfig {
	private static SqlSessionFactory sqlsession_f;
	
	//static 초기화 블럭, 프로그램 실행 시 단 한번만 실행되기 때문에 임의로 실행할 필요가 없어진다.
	static {
		try {
			//config.xml 의 경로 작성
			String resource = "./mybatis/config/config.xml";
			//해당 경로에 있는 config.xml을 객체로 읽어온다.
			Reader reader = Resources.getResourceAsReader(resource);
			//전달한 config.xml 객체를 토대로 Factory를 빌드한다.
			sqlsession_f = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			throw new RuntimeException("초기화 문제 발생");
		}
	}
	
	public static SqlSessionFactory getSqlMapInstance() {
		return sqlsession_f;
	}
}

3. SQL을 작성한다.

blog.xml

xml파일은 꼭 소문자로 시작해야 한다. (오류가 많이남...경험에서 나오는 말)

namespace를 지정하고, sql문을 작성한다.

id: 해당 sql문의 이름

parameterType: 외부에서 받아올 값의 타입

resultType: 리턴받을 값의 타입 (_int는 java의 int타입이다.)

#{[받아올 값의 이름]}을 통해 값을 맞춰 넣는다.

<?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="Blog">
	<select id="searchAge" parameterType="string" resultType="_int">
		Select AGE FROM BLOG_TABLE WHERE NAME=#{name}
	</select>
</mapper>

4. DAO 작성

blog.java

session.[사용할 쿼리의 DML형식](쿼리id, [필요할 경우 매개변수]); 로 작성한다.

package blog.dao;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import mybatis.config.SqlMapConfig;

public class BlogDAO {
	//SqlSessionFactory를 SqlMapConfig를 통하여 생성한다.
	SqlSessionFactory sqlsession_f = SqlMapConfig.getSqlMapInstance();
	SqlSession session;
	
	public BlogDAO() {
		//SqlSessionFactory에서 session을 할당받는다.
		//이 때 openSession에 true를 주어야 자동 커밋이 된다.
		//default는 false이다.
		session = sqlsession_f.openSession(true);
	}
	
	public int searchAge(String name) {
		//session을 통해 쿼리를 실행하고 값을 받아온다.
		return session.selectOne("Blog.searchAge", name);
	}
}

5. 실제 실행

TestMain.java

package blog.dao;

public class TestMain {
	public static void main(String[] args) {
		BlogDAO dao = new BlogDAO();
		int age = dao.searchAge("heekng");
		System.out.println(age);
	}
}

위처럼 코드 작성시 실행 결과는 다음과 같다.

정상적으로 출력되며, 이를 통해 하나의 문서에는 하나의 언어만 작성해서 독립성을 주고, 위에서 말한 것처럼 분업이 되어 작업 효율이 좋아진다.

 

개발 회사에서는 MyBatis와 JPA를 사용하는데 MyBatis의 비율이 더 크다.

JPA: DB를 JAVA에 맞춰서 이용하는 것, 자식을 만들면 부모까지 테이블이 만들어진다.

반응형

'Java & Kotlin > Spring Data' 카테고리의 다른 글

[QueryDSL] 프로젝션  (0) 2022.05.14
[QueryDSL] QueryDSL 기본문법  (0) 2022.05.11
[QueryDSL] QueryDSL 시작하기  (0) 2022.05.10
[JPA] UniqueConstraint와 Embedded field  (0) 2022.05.07
[JPA]영속성 전이 CASCADE  (0) 2022.04.21
[MyBatis] 동적쿼리(동적 태그)  (0) 2021.05.13