bdfgdfg

Mybatis 프레임워크 본문

웹프로그래밍/Java

Mybatis 프레임워크

marmelo12 2023. 11. 7. 21:49
반응형

Mybatis란?

자바의 JDBC를 통한 RDBMS 관련 쿼리문 작성을 좀 더 편하게 작성하게 도와주는 프레임워크.

 -> 귀찮고 반복적인 JDBC를 통한 DB 쿼리를 작성하는 코드를 줄일 수 있음 (Mapper)

코드에 쿼리문을 작성하던 JDBC와는 달리 XML에서 쿼리문을 작성한다는 특징이 있음.

https://velog.io/@qotndus43/MyBatis-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B3%A0-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90

 

myBatis의 초기화 과정과 흐름은 위 그림과 같다.

1. Application단에서 SqlSessionFactoryBuilder를 통해 Mybatis 관련 설정파일을 읽어들이고 SqlSessionFactory를 생성.

2. Applcation단에서 DB 통신을 위해 SqlSessionFactory로부터 SqlSession객체를 가져옴.

3. SqlSession으로 부터 MapperInterface의 자식객체(쿼리문이 작성된 xml <-> MapperInterface 매핑)를 가져온다.

4. 해당 객체로부터 메소드를 호출하여 DB와 통신.

 

Mybatis의 주요 컴포넌트

이름 설명
MyBatis 설정파일 (mybatis-config.xml) DB의 설정정보, Mapping 파일의 경로등을 설정하는 XML 파일
SqlSessionFactoryBuilder MyBatis 설정파일을 읽고 SqlSessionFactory를 생성.
단한번 SqlSessionFactory를 생성하고 더이상 유지하지 않는게 좋다.
SqlSessionFactory SqlSession을 생성을 위한 팩토리 객체. 
Builder를 통해 초기화된 이후 단 하나의 인스턴스만을 가지고 있는게 좋다. 
(싱글턴등의 클래스로 SqlSessionFactory를 하나만 가지고 있는게 좋음. 초기화 과정 또한 톰캣과 같은 WAS는 멀티쓰레드 환경이기에 Thread-Safe하게 작업해야한다)
SqlSession Mapperd인터페이스의 객체를 가져와 쿼리문의 실행이나 트랜잭션 관리를 수행
thread-safe 하지 않기에 하나의 SqlSession에 여러 스레드가 경합되지 않도록 해야한다.
Mapping File (mapper.xml) 쿼리문과 객체 매핑 설정을 하는 XML 파일

 

사용법

뭔가를 하기전에 myBatis 라이브러리를 가져와야함.

간단하게 java Project환경에서만 테스트할 예정이니 maven repository에서 mybatis jar파일을 가져온후 넣어주자. (ojdbc도)

 

먼저 주요 컴포넌트에서 보았듯이 SqlSessionFactoryBuilder를 통해 Mybatis 설정파일을 읽어들이고, SqlSessionFactory를 생성하는게 첫번째.

1. Mybatis 설정파일 추가

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<properties resource="config/db.properties"> <!-- driver,url관련 정보를 따로 빼둠 -->
	</properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    
  </mappers>
</configuration>

위와같이 mybatis-config.xml 파일을 추가해준다.

여기서 중요한건 해당 설정과 관련된 파일들이 config 경로아래에 있어야하는가봄.

 

 

2. Mybatis 싱글턴 클래스 생성

이제 SqlSessionFactoryBuilder를 통한 초기화와 하나의 SqlSessionFactory인스턴스를 들고있는 MyBatis 싱글턴 클래스를 추가해준다.

package mybatisSample;

import java.io.IOException;
import java.io.InputStream;

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

public class Mybatis {
	private Mybatis() {}
	
	private static SqlSessionFactory factory = null;
	private static Object factoryLock = new Object();
	
	public static SqlSession getSqlSession(boolean autoCommit) {
		if(factory == null) {
			synchronized(factoryLock) {
				if(factory == null) {
					String resource = "config/mybatis-config.xml";
					InputStream inputStream = null;
					try {
						inputStream = Resources.getResourceAsStream(resource);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					factory = new SqlSessionFactoryBuilder().build(inputStream);
				}
			}
		}
		
		return factory.openSession(autoCommit);
	}
}

Mybatis 프레임워크는 SQL관련 프레임워크이고, 서버측에서 사용되는 프레임워크이다보니 멀티쓰레드 환경일 경우가 높아 최초 1회 SqlSessionFactory를 초기화하는 과정을 threadSafe하게 처리.

 

또한 openSession메소드 호출 시 인자로 autoCommit여부를 묻는데 이건 따로 외부에서 호출할 때 결정할 수 있게끔처리.

 

3. Mapper.xml과 MapperInterface생성

그전에 myBatis 설정파일에 setting 노드를 추가해준다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<properties resource="config/db.properties"> <!-- driver,url관련 정보를 따로 빼둠 -->
	</properties>
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true" /> <!--  --!>
		<setting name="jdbcTypeForNull" value="NULL" /> <!-- 값이 없다면 실제로도 NULL로 처리 -->
	</settings>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>

	</mappers>
</configuration>

 

첫번째 세팅인 mapUnderscoreToCamelCase 세팅의 경우.

Table의 칼럼명은 보통 SnakeCase로 작성하고, 웹환경에서 자주쓰이는 DTO,VO에서 칼럼과 대응되는 필드명은 CamelCase로 쓰이는데 이 두 Case를 적절하게 변환해주는 세팅값.

https://m.blog.naver.com/sky_14786/221799604116 위는 예시.

두번쨰인 jdbcTypeForNull은 쿼리문에 들어오는값이 NULL일시 어떻게 처리할지에 대한 세팅. 그대로 null로 저장되게 value에도 NULL로 세팅했음.

 

이제 쿼리문에 매핑될 Mapper.xml과 Mapper.java 파일을 만들어준다.

먼저 Mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Member.mapper.MemberMapper">
  
</mapper>

 

그리고 Mapper.java

package Member.mapper;

public interface MemberMapper {
	
}

 

(테이블은 Member로 미리 만들어두었고, MemberVO클래스 또한 따로 만들어둠)

또한 해당 Mapper.xml을 mapper설정파일을 mybatis-config.xml에 추가해준다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<properties resource="config/db.properties"> <!-- driver,url관련 정보를 따로 빼둠 -->
	</properties>
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true" />
		<setting name="jdbcTypeForNull" value="NULL" /> <!-- 값이 없다면 실제로도 NULL로 처리 -->
	</settings>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- resource, class방식등이있음. xml은 resource로 매핑. interface는 class로 매핑 -->
		<!-- <mapper resource="co/yedam/board/mapper/BoardMapper.xml" />  -->
		<mapper class="Member.mapper.MemberMapper" />
	</mappers>
</configuration>

 

이제 단일 Select 조회 쿼리문과 전체 Select 조회 쿼리문을 추가하면

Mapper.java는

package Member.mapper;

import java.util.List;
import Member.service.MemberVO;

public interface MemberMapper {
	public MemberVO select(String mid);
	public List<MemberVO> selectAll();
}

mapper.xml은

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Member.mapper.MemberMapper">
   <select id="selectAll" resultType="Member.service.MemberVO">
    SELECT * FROM MEMBER
  </select>
  <select id="select" resultType="Member.service.MemberVO" parameterType="String">
  	SELECT * FROM MEMBER WHERE MID = #{mid}
  </select>
</mapper>

위와 같음.

 

이제 메인메소드가 존재하는 메인 클래스에서 실행해보자.

package mybatisSample;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import Member.mapper.MemberMapper;
import Member.service.MemberVO;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SqlSession session = Mybatis.getSqlSession(true);
		MemberMapper mapper = session.getMapper(MemberMapper.class);
		List<MemberVO> vos = mapper.selectAll();
		MemberVO vo = mapper.select("M001");
		
		
		System.out.println(vos);
		System.out.println(vo);
	}

}

 

정상출력된다.

 

 

요약.

1. Mybatis-config.xml을 생성후 SqlSessionFatoryBuilder를 통한 SqlSessionFactory초기화

2. 테이블과 대응되는 Mapper.xml과 Mapper.java 파일 생성. Mapper.xml은 Mybatis-config.xml에 등록해준다.

3. Mapper.xml에 쿼리문 작성 및 해당 쿼리문 노드에는 id값이 Mapper.java의 메소드명과 일치해야함.

 

 

 

반응형

'웹프로그래밍 > Java' 카테고리의 다른 글

자바 소켓통신  (0) 2023.10.08
자바 소켓프로그래밍  (0) 2023.08.01
자바의 직렬화  (0) 2023.08.01
스트림(Stream)  (0) 2023.07.30
람다  (0) 2023.07.30
Comments