본문 바로가기
IT Study/Spring

Spring - Mybatis DB 직접 연동하기 및 insert 적용

by hhyyyjun 2023. 1. 3.

Mybatis란?

Mybatis는 자바 오브젝트와 SQL사이의 자동 매핑 기능을 지원하는 프레임워크이다.

SQL을 별도의 파일로 분리해서 관리하게 해준다.

Mybatis 특징

쉬운 접근성과 코드의 간결함(가독성)

JDBC의 모든 기능을 Mybatis가 대부분 제공한다.

복잡한 JDBC코드를 걷어내며 깔끔한 소스코드를 유지할 수 있다.

수동적인 파라미터 설정과 쿼리 결과에 대한 맵핑 구문을 제거할 수 있다.

SQL문과 프로그래밍 코드의 분리

SQL에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일하지 않아도 된다.

동작방법

1) XML 파일에 저장된 SQL문을 실행

2) 실행의 결과를 VO(Java객체)에 자동으로 매핑까지 수행함

1. 플러그인 설치

Eclipse 마켓에서 mybatis 검색 후 사진에 보이는 2개의 플러그인을 설치하면 된다.

2. pom.xml에 라이브러리 추가

<!-- mybatis -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.3.1</version>
</dependency>
<dependency>
	<groupId>org.apache.ibatis</groupId>
	<artifactId>ibatis-core</artifactId>
	<version>3.0</version>
</dependency>

3. DB 연동에 필요한 SQL문을 xml 파일에 저장

3-1) 프로젝트 - src에 xml 파일 생성

3-2) 테이블명-mapping.xml 으로 파일명 설정

3-3)src/main/resources에 매핑들만 저장할 패키지 생성

src에 생성한 파일들을 해당 패키지에 드래그앤 드롭으로 파일 이동

mapper 태그의 namespace 속성 prefix와 비슷한 개념, 기능들을 가지고 있는 대표 이름이다.

3-4) 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="BoardDAO">
<!-- namespace나 id는 중복되면 안된다. 다만 다른 namespace에서는 아이디 중복 가능 -->
<insert id="insertBoard">
	INSERT INTO BOARD(BID, TITLE, WRITER) VALUES((SELECT NVL(MAX(BID),0)+1 FROM BOARD), #{title}, #{writer})
</insert>

</mapper>

4. sql-map-config.xml 설정이 필요

4-1) src 경로에 config.xml 파일 생성

4-2) 파일 이름은 sql-map-config.xml로 설정

4-3) 스키마 변경

<?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>

</configuration>

이후 같은 패키지(mappers)로 드래그 앤 드롭

5. DB연동하기

스프링 연동없이 사용하기 위해서는 직접 DB연동 정보를 작성해야 함

spring과 연동할 때는 DB연동정보가 applicationContext에 있기 때문에 별도 작성할 필요는 없다.

5-1) src/main/resources에 db.properties 파일 생성

5-2) db.properties에서 jdbc 설정

5-3) 4번에서 생성한 sql-map-config.xml 파일에 각 파일 연결 및 DataSource 설정

<?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>

	<!-- DB연동정보 파일과 연결 -->
	<properties resource="db.properties"></properties>

	<!-- 별칭(alias) 설정 -->
	<!-- 어떤 VO를 뭐라고 부를지 -->
	<!-- 별칭은 여러개 사용할 수 있음 -->
	<typeAliases>
		<typeAlias type="com.kim.biz.board.BoardVO" alias="board" />
	</typeAliases>

	<!-- DataSource 설정 -->
	<!-- db.properties에서 설정한 value값 설정 -->

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driverClassName}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>

	<!-- SQL Mapper 파일 연결 -->
	<mappers>
		<mapper resource="mappings/board-mapping.xml" />
	</mappers>

</configuration>

6. SqlSession 객체 사용할 FactoryBean 클래스 생성

package com.kim.biz.common;
import java.io.Reader;

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 SqlSessionBean {
	//Mybatis로 DAO 클래스의 CRUD 메서드를 사용
	//Mybatis에서 제공하는 SqlSession 객체를 사용해야 한다.
	//SqlSession은 팩토리 패턴으로 관리되기 때문에 팩토리 객체가 필요하다.
	
	private static SqlSessionFactory sessionFactory = null;
	static {
		try {
			if(sessionFactory==null) {
				//이곳의 작업은 스트림을 사용한다.
				//외부요인으로 인한 에러가 자주 발생하기 때문에 예외처리
				
				//builder를 이용해서 SSF객체를 생성할 예정
				//builder는 Mybatis 설정파일(sql-map-config.xml)을 보고서 메모리에 로딩(적재)해서 SSF객체를 생성한다.
				//설정파일 로딩을 위해 입력 스트림(Reader)을 사용
				Reader reader = Resources.getResourceAsReader("sql-map-config.xml"); //파일을 읽을 땐 리더가 필요
				sessionFactory = new SqlSessionFactoryBuilder().build(reader); //리더로 팩토리 만들고
			}
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static SqlSession getSqlSessionInstance() {
		return sessionFactory.openSession(); //팩토리로 세션 만듦
	}
}

7. BoardDAO.java

SqlSession 객체 주입 및 dao 작성

package com.kim.biz.board.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.kim.biz.board.BoardVO;
import com.kim.biz.common.SqlSessionBean;

public class BoardDAO3 {
	private SqlSession mybatis;
	
	public BoardDAO3() {
		//생성자 주입
		mybatis = SqlSessionBean.getSqlSessionInstance();
	}
	
	public void insertBoard(BoardVO vo) {
		mybatis.insert("BoardDAO.insertBoard",vo);
		mybatis.commit();
        //메서드가 실행될 때 해당 기능을 인지만 해둔상태(대기하고 있음)
        //커밋을 만나는 순간 기능 수행
	}
	public void updateBoard(BoardVO vo) {
		mybatis.update("BoardDAO.updateBoard",vo);
		mybatis.commit();
	}
	public void deleteBoard(BoardVO vo) {
		mybatis.delete("BoardDAO.deleteBoard",vo);
		mybatis.commit();
	}
	public BoardVO selectOneBoard(BoardVO vo) {
		return mybatis.selectOne("BoardDAO.selectOneBoard",vo);
	}
	public List<BoardVO> selectAllBoard(BoardVO vo) {
		return mybatis.selectList("BoardDAO.selectAllBoard",vo);
	}
}

resultMap 속성

본인이 직접 데이터를 변동시켜야 할 때 사용한다.

id는 고유 값을 의미하며, result는 pk가 아닌 일반 칼럼 요소들을 의미한다.

칼럼명과 데이터가 저장될 멤버변수명이 다를 시 사용된다.

CDATA (문자데이터)

- 마이바티스 문법이 아닌 XML 문법이다.

- xml파서가 컴파일러마냥 해석을 통해 설정을 이해한다.

- CDATA라는 영역을 설정하면, 해당 영역의 글은 XML파서가 해석하지 않는다.

- 따라서 부등호를 쓰더라도 예외가 되는 것

댓글