[Spring] MyBatis

young-gue Park·2023년 10월 16일
0

Spring

목록 보기
6/14
post-thumbnail

⚡ MyBatis


❗ 스프링 관련 포스트지만 이 글에서는 스프링을 사용하지 않을겁니다. 아이러니하죠.

📌 MyBatis란?

🔷 SQL 매핑 프레임워크

  • SQL문과 저장프로시저 등의 매핑을 지원하는 퍼시스턴스 프레임워크(persistence framework)
  • JDBC로 처리하는 상당부분의 코드와 파라미터 설정 및 결과 처리를 대신해준다.
  • Map 인터페이스 그리고 자바 POJO 를 설정 데이터베이스와 매핑해서 사용할 수 있다.
  • XML과 Annotation 설정을 통해 사용할 수 있다.

🔷 MyBatis - 시작하기

  • mybatis-x.x.x.jar 파일을 프로젝트에 추가
  • maven 프로젝트를 사용한다면 pom.xml에 의존성 추가
  • properties 설정은 외부에 옮길 수 있다. 자바 프로퍼티 파일 인스턴스에 설정할 수도 있고, properties 요소의 하위 요소에 둘 수도 있다.

문서 순서를 잘 지킬 것!

environments와 mappers는 필수 설정이다.

🔷 실습 프로젝트 구조

🖥 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"/>

  <typeAliases>
  	<typeAlias type="com.bzeromo.board.model.dto.Board" alias="Board"/>
  </typeAliases>

  <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>
    <mapper resource="mappers/boardMapper.xml"/>
  </mappers>
</configuration>

🖥 db.properties

url=jdbc:mysql://localhost:3306/bzeromo_board?serverTimezone=UTC
driver=com.mysql.cj.jdbc.Driver
username=bzeromo
password=1234

🔷 MyBatis 구성

  1. 환경설정파일
  • MyBatis 전반에 걸친 세팅
  • DB접속정보, 모델 클래스 정보, 매핑정보
  1. Mapper
  • 사용할 SQL문 정의
  1. Mapped Statement
  • SqlSession 빌드 및 사용
  • SQL문 실행
  1. Input/Output
  • SQL 실행 시 필요한 데이터
  • SQL 실행결과

🔷 SqlSessionFactory
‐ 모든 마이바티스 애플리케이션은 SqlSessionFactory 인스턴스를 사용한다.
‐ SqlSessionFactory는 SqlSession을 만든다.

🔷 SqlSession
‐ 데이터베이스에 대해 SQL 명령어를 실행하기 위한 메서드를 포함한다.

// SqlSessionFactoryBuilder를 사용하여
// SqlSessionFactory 인스턴스를 생성한다.
String resource = "config/mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

📌 실전! 게시판 만들기

👍 boardDao와 Board DTO, board가 담긴 데이터베이스는 이전 실습에서 사용한 것을 그대로 사용한다.

🖥 com.bzeromo.board.config.MyAppSqlConfig

package com.bzeromo.board.config;

import java.io.IOException;
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 MyAppSqlConfig {
	
	private static SqlSession session;
	//session 생성
	
	static {
		//MyBatis 설정 파일 불러오기
		try {
			String resource = "config/mybatis-config.xml";
			Reader reader = Resources.getResourceAsReader(resource);
			
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
			
			//true 옵션 설정 시 자동 커밋
			session = sqlSessionFactory.openSession(true);
			System.out.println("세션 생성 성공");
		} catch (IOException e) {
			System.out.println("세션 생성 실패");
		}
		
	}
	
	public static SqlSession getSession() {
		return session;
	}
}

🖥 boardMapper.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="com.bzeromo.board.model.dao.BoardDao">
	<!-- 매핑 시키고 싶은 것을 넣어놓고 사용한다. 프로퍼티명과 컬럼명이 겹치는 것은 굳이 없어도 된다. -->
	<resultMap type="Board" id="boardMap">
		<result column="id" property="id"/>
		<result column="writer" property="writer"/>
		<result column="title" property="title"/>
		<result column="content" property="content"/>
		<result column="view_cnt" property="viewCnt"/>
		<result column="reg_date" property="regDate"/>
	</resultMap>
	
	<!-- 전체글 조회 -->
	<!-- 누구(BoardDao의 메서드 중)와 매핑 시킬 것인가? -->
	<!-- 반환형으로 풀패키지명을 작성한다. 타이핑을 줄이기 위해 typeAliases를 사용할 수 있다. -->
	<select id="selectAll" resultType="Board">
	<!-- 클래스의 필드명과 테이블의 컬럼명이 다를 때 발생하는 오류를 막기 위해 컬럼병의 별칭으로 필드명을 넣는다. -->
		SELECT id, content, writer, title, view_cnt AS viewCnt, date_format(reg_date, '%y-%m-%d') AS regDate 
		FROM board;
	</select>
	
	<!-- 상세글 조회 -->
	<!-- 메서드에 들어오는 파라미터의 자료형을 지정해준다. 매개변수가 여러개면 DTO 혹은 map 인터페이스를 활용한다. -->
	<!-- #{} 안에 들어가는 단어는 사실 어느 것이든 상관없다. 다만 가독성을 위해 잘 써주자. -->
	<select id="selectOne" resultMap="boardMap" parameterType="int">
		SELECT *
		FROM board
		WHERE id = #{id};
	</select>
	
	<!-- 게시글 등록 -->
	<insert id="insertBoard" parameterType="Board">
			INSERT INTO board(title, writer, content)
			VALUES (#{title}, #{writer}, #{content})
	</insert>
	
	<!-- 게시글 삭제 -->
	<delete id="deleteBoard" parameterType="int">
		DELETE FROM board
		WHERE id = #{id};
	</delete>
	
	<!-- 조회수 증가 -->
	<update id="updateViewCnt" parameterType="int">
		UPDATE board
		SET view_cnt = view_cnt + 1
		WHERE id = #{id};
	</update>
	
	<!-- 게시글 수정 -->
	<!-- 수정 날짜까지 적용 -->
	<update id="updateBoard" parameterType="Board">
		UPDATE board
		SET title = #{title}, content = #{content}, reg_date = now()
		WHERE id = #{id};
	</update>
</mapper>

parameterMap은 현재 권장되지 않는다.

🖥 com.bzeromo.board.test.Test

package com.bzeromo.board.test;

import com.bzeromo.board.config.MyAppSqlConfig;
import com.bzeromo.board.model.dao.BoardDao;
import com.bzeromo.board.model.dto.Board;

public class Test {
	public static void main(String[] args) {
		//이제 굳이 Impl을 따로 구현할 필요 없다!
		BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
	
		//게시글 추가
		Board board = new Board("하 myBatis 쉽네요", "박모씨", "So EZ ㅋㅋ");
		dao.insertBoard(board);
		
		//게시글 삭제
		dao.deleteBoard(11);
		
		//조회수 증가
		dao.updateViewCnt(5);
		
		//게시글 수정
		Board bo = dao.selectOne(6);
		bo.setTitle("대답 개 잘함");
		bo.setContent("드루와");
		dao.updateBoard(bo);
		
		//전체 게시글 조회
		for(Board b : dao.selectAll()) {
			System.out.println(b);
		}
		
		//특정 게시글 조회
		System.out.println(dao.selectOne(6));
	}
}

🖨 1. 전체 게시글 조회

🖨 2. 특정 게시글 조회

🖨 3. 게시글 추가 + 전체 게시글 조회

🖨 4. 게시글 삭제 + 전체 게시글 조회

🖨 5. 조회수 증가 + 전체 게시글 조회

🖨 6. 게시글 수정 + 전체 게시글 조회


내일은 웹과 스프링까지 연동해본다.

profile
Hodie mihi, Cras tibi

0개의 댓글