열심히 끝까지

디바이스 융합 자바(Java) day78 - Mybatis 프레임워크(설치 및 설정) 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day78 - Mybatis 프레임워크(설치 및 설정)

노유림 2022. 10. 4. 15:42

[Mybatis 프레임워크]

  >> Ibatis라는 이름으로 시작됨
> Ibatis 사용 이유
     1) DB연동을 담당하는 JAVA 코드가 매우 긴데
        그 자바 코드를 1~2줄로 줄일 수 있음      
         >> 자바 코드를 줄이기 위함 [ 가독성 ]   
     2) SQL 문은 JAVA 코드에서 분리하여 XML 파일로 별도 관리 가능 [ 응집도 ↑]
   >> 유지보수 용이로 이어지는 코드이기 때문에 사용

※ 팀 프로젝트에 적용하는 방법?
    1) 우리가 어필해야 하는 것은 여러가지 버전의 DAO를 빠르게 교체 가능
           > Service -> 2-Layered 아키텍쳐
    2) 상대적으로 간단한 기능(회원가입, 탈퇴, 게시글 등록, 삭제, 댓글 등록, 등..)의 CRUD를
        Mybatis로 구현
           > MybatisDAO를 제작
    3) 상대적으로 복잡한 기능들의 CRUD는 기존의 JDBC or JDBCTemplate으로 구현

※ 동작 방법
    1) XML 파일에 저장된 SQL문을 실행
    2) 실행의 결과를 VO(JAVA 객체)에 자동으로 매핑까지 수행함


>> MyBatis 설치
Eclipse Marketplace   
 > mybatis 검색 > 나오는 MyBatis(2개 항목) 플러그인 설치


>> 이때, 나오는 모든 설치 사항은 all accept + all install(모두 선택) 할 것 

     >> 설치가 완료되면 Maven Dependence에 다음 항목 있는지 확인

           + 설치가 완료되면 restart가 나오게 되는데 restart 눌러서 재시작 할 것

 

※ 설정
1) 플러그인 설치(2개)

    : mybatis 플러그인 2개


2) pom.xml에 라이브러리 파일 (2개) 추가

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

>> Mybatis외에 Ibatis도 다운받아 사용 : ibatis에서 사용해야하는 항목 존재하기 때문

 

3) DB 연동에 필요한 SQL문을 XML 파일에 저장
src > new > other > mybatis 검색 >xml Mapper 로 파일 생성


> src.main.resources에 mappings 라는 package 생성
> 생성한 패키지에 위에서 만든 xml Mapper 넣기


  ex ) board-Mapping, member-Mapping 등....


4) sql-map-config.xml 작성
단독적으로 db에 연동이 불가
 >> 연결하려면?
      1. db 정보를 직접 넣기
      2. spring 이용해서 연동하기

  >> 오늘은 1번 사용할 것
db 정보를 담아놓는 file 따로 작성(db.properties)


jdbc.driverClassName=사용하는 데이터베이스 드라이버
jdbc.url=데이터베이스 url
jdbc.username=유저 이름
jdbc.password=비밀번호

예시, =옆에는 자신의 정보 입력



>> spring과 연동할 때는 db 연동 정보가 있기 때문에 별도 작성 안함

 

>> sql-map-config.xml

    : mybatis Generator Configuration File 로 작성

    : 아래는 설명을 위한 코드

       > 만약 다음 코드가 안 먹히면 그 다음 코드로 작성해볼 것 

-- sql-map-config.xml 작성

<?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" />
	
	<!-- 별칭(Alias) 설정 -->
	<!-- board-mapping 이름과 같은 이름으로 연결 -->
	<!-- 별칭 여러 개 설정 가능함 : 헷갈리지 않게 사용할 것 -->
	<typeAliases>
		<typeAlias type="com.ryo.biz.board.BoardVO" alias="board" />
	</typeAliases>
	
	<!-- DataSource 설정 : db와 연동하려면 반드시 필요!! -->
	<!-- spring과 연동하지 않았기 때문에 직접 연동 -->
	<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>
<?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" />
   <!-- 별칭(Alias) 설정 -->
   <typeAliases>
      <typeAlias type="com.ryo.biz.board.BoardVO" alias="board"/>
   </typeAliases>
   
   <!-- DataSource 설정 -->
   <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>

 

 

다음 board-mapping 작성

- 위에 쓴  sql-map-config.xml의 board는 board-mapping에 사용

- mapping과 configuration의 차이

   1. 둘의 DOCTYPE 선언 방식 차이

 >> configuration

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

 >> mapper

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

 

---board-mapping.xml

<?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">
<!-- sql 명령어를 한가득 담을텐데 그 때 부를 이름을 매핑 시키기 위해 namespace에 작성 -->
<!-- namespace는 필수속성이기에 매핑할 DAO 꼭 작성 -->

	<!-- namespace 내부에 id는 중복 불가(하지만 다른 xml에 현재 있는 id가 있어도 괜찮음) -->
	<insert id="insertBoard">
		INSERT INTO BOARD(BID,TITLE,WRITER,CONTENT) VALUES((SELECT NVL(MAX(BID),0)+1 FROM BOARD),#{title},#{writer},#{content})
	</insert>
	
	<update id="updateBoard">
		UPDATE BOARD SET TITLE=#{title}, CONTENT=#{content} WHERE BID=#{bid}
	</update>
	
	<delete id="deleteBoard">
		<![CDATA[
		DELETE BOARD WHERE BID=#{bid}
		]]>
		<!-- DELETE BOARD WHERE BID<=20 처럼 부등호가 쓰고 싶다면?(태그로 인식되는 문자열) -->
	</delete>
	
	<!-- select는 output이 존재하기 때문에 누구랑 맞출 것인지 적어주어야 함 resultType="얼라이어스/별칭" -->
	<select id="selectOneBoard" resultType="board">
		SELECT * FROM BOARD WHERE BID=#{bid}
	</select>
	
	<select id="selectAllBoard" resultType="board">
		SELECT * FROM BOARD 
		WHERE TITLE LIKE '%'||#{searchContent}||'%' 
		ORDER BY BID DESC
	</select>

</mapper>

 

 

기본 세팅이 끝나면

1. BoardDAO3의 CRUD를 이용하기 위한 SqlSessionFactoryBean 제작

2. MyBatis를 이용한 BoardDAO3를 생성하고,

3. 돌아가게 할 파일 제작

 

1. BoardDAO3의 CRUD를 이용하기 위한 SqlSessionFactoryBean 제작 : SqlSessionBean.java

package com.ryo.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 객체를 사용해야한다!
	//   -> Factory 패턴
	
	private static SqlSessionFactory sessionFactory=null;
	static {
		try {
			if(sessionFactory==null) {
				// 이곳의 작업은 스트림을 사용합니다.
				// 외부 요인으로 인한 에러가 자주 발생하기 때문에 예외처리했습니다.
				
				// builder를 이용해서 SqlSessionFactory 객체를 생성할 예정
				// builder는 Mybatis 설정파일(sql-map-config.xml)을 로딩하면서
				// SqlSessionFactory 객체를 생성함
				
				// 설정파일 로딩을 위해 입력스트림(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();
	}
}

 

2. MyBatis를 이용한 BoardDAO3 제작(앞에서 제작한 SqlSessionFactoryBean import) : BoardDAO3.java

package com.ryo.biz.board.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

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

public class BoardDAO3 {
	private SqlSession mybatis;
	public BoardDAO3() {
		// 생성자 주입
		mybatis=SqlSessionBean.getSqlSessionInstance();
	}
	public BoardVO selectOneBoard(BoardVO vo) {
		return mybatis.selectOne("BoardDAO.selectOneboard",vo);
	}
	// 글 모두 보기
	public List<BoardVO> selectAllBoard(BoardVO vo) {
		return mybatis.selectList("BoardDAO.selectAllBoard",vo);
	}
	
	
	// 글 추가
	public void insertBoard(BoardVO vo) {
		System.out.println("★");
		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();
	}	

}

 

3. 돌아가게 할 파일 제작 : MybatisClient.java

package com.ryo.biz.common;

import java.util.List;

import com.ryo.biz.board.BoardVO;
import com.ryo.biz.board.impl.BoardDAO3;

public class MybatisClient {
	public static void main(String[] args) {
		BoardDAO3 boardDAO=new BoardDAO3();
		
		BoardVO vo = new BoardVO();
		vo.setTitle("마이바티스");
		vo.setWriter("작은 티모");
		vo.setContent("mybatis");
		boardDAO.insertBoard(vo);
		
		vo.setSearchCondition("TITLE");
		vo.setSearchContent("이");
		List<BoardVO> datas=boardDAO.selectAllBoard(vo);
		
		for(BoardVO v : datas) {
			System.out.println(v);
		}
	}
}

Ex ) 적용 하고 나서의 다른 돌아가는 파일 제작 후 결과 캡쳐본

package com.ryo.biz.common;

import java.util.List;

import com.ryo.biz.board.BoardVO;
import com.ryo.biz.board.impl.BoardDAO3;

public class MybatisClient {
	public static void main(String[] args) {
		BoardDAO3 boardDAO=new BoardDAO3();
		
		BoardVO vo = new BoardVO();
		vo.setTitle("마이바티스2");
		vo.setWriter("티모");
		vo.setContent("mybatis 적용");
		boardDAO.insertBoard(vo);
		
		vo.setSearchCondition("TITLE");
		vo.setSearchContent("이");
		List<BoardVO> datas=boardDAO.selectAllBoard(vo);
		
		for(BoardVO v : datas) {
			System.out.println(v);
		}
	}
}

 


 

+) resultMap 속성
    : output이 복잡한 것을 내가 만듦
   : 어떤 PK값을 가지고 있는지 확인이 다이렉트로 가능

<?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">
<!-- sql 명령어를 한가득 담을텐데 그 때 부를 이름을 매핑 시키기 위해 namespace에 작성 -->
<!-- namespace는 필수속성이기에 매핑할 DAO 꼭 작성 -->

	<!-- 필요한 조 사용 -->
	<resultMap type="board" id="boardResult">
		<id property="bid" column="BID" />
		<result property="title" column="TITLE" />
		<result property="writer" column="WRITER" />
		<result property="content" column="CONTENT" />
	</resultMap>

	<!-- namespace 내부에 id는 중복 불가(하지만 다른 xml에 현재 있는 id가 있어도 괜찮음) -->
	<insert id="insertBoard">
		INSERT INTO BOARD(BID,TITLE,WRITER,CONTENT) VALUES((SELECT NVL(MAX(BID),0)+1 FROM BOARD),#{title},#{writer},#{content})
	</insert>
	
	<update id="updateBoard">
		UPDATE BOARD SET TITLE=#{title}, CONTENT=#{content} WHERE BID=#{bid}
	</update>
	
	<delete id="deleteBoard">
		<![CDATA[
		DELETE BOARD WHERE BID=#{bid}
		]]>
		<!-- DELETE BOARD WHERE BID<=20 처럼 부등호가 쓰고 싶다면?(태그로 인식되는 문자열) -->
	</delete>
	
	<!-- select는 output이 존재하기 때문에 누구랑 맞출 것인지 적어주어야 함 resultType="얼라이어스/별칭" -->
	<select id="selectOneBoard" resultType="board">
		SELECT * FROM BOARD WHERE BID=#{bid}
	</select>
	
	<!-- 다음과 같이 위에서 Map으로 묶어서 output 제공  -->
	<select id="selectAllBoard" resultMap="boardResult">
		SELECT * FROM BOARD 
		WHERE TITLE LIKE '%'||#{searchContent}||'%' 
		ORDER BY BID DESC
	</select>

</mapper>



+) CDATA(Character Data)(문자 데이터)
DELETE BOARD WHERE BID<=20 처럼 
부등호가 쓰고 싶다면?(태그로 인식되는 문자열)
>> Mybatis 문법이 아니라 "XML 문법"이다!!!!
        : 자주 사용하게 될 문법
        : XML 파서가 해석을 통해 설정을 이해하는데...
        : CDATA 영역을 설정하면, 그 영역은 XML 파서가 해석하지 않음
           >> 부등호를 써도 논외로 해당

<delete id="deleteBoard">
<![CDATA[
DELETE BOARD WHERE BID=#{bid}
]]>
<!-- DELETE BOARD WHERE BID<=20 처럼 부등호가 쓰고 싶다면?(태그로 인식되는 문자열) -->
</delete>



+) 가독성을 위해서라도 앞으로의 SQL 문은 전부 대문자로 작성