능글맞은 구렁이

Spring-Mybatis 본문

Framework/Spring

Spring-Mybatis

보라색츄르 2021. 6. 29. 10:54

*Mybatis의 기본 구조*

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">
	<insert id="insertBoard">
		insert into board (seq, title, writer, content)
		values ((select nvl(max(seq), 0)+1 from board), #{title}, #{writer},
		#{content})
	</insert>
	<update id="updateBoard">
		update board set title=#{title}, content=#{content} where seq=#{seq}
	</update>
	<delete id="deleteBoard">
		delete board where seq=#{seq}
	</delete>
	<select id="getBoardList" resultType="board">
		select * from board where title like '%'||#{searchKeyword}||'%' order by seq desc
	</select>
</mapper>

1. <?xml version="1.0" encoding="UTF-8"?> 

    xml선언부

 

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

   ㄱ) 문서타입

   ㄴ) sql 작업을 하려면 반드시 mapper로 잡혀있어야 하고 DTD또한 mapper로 잡혀 있어야하며 주소도 mapper로 

        잡혀 있어야 한다.

 

3. <mapper namespace="자바코드에서 사용할 이름"></mapper>

   전체태그(엘리먼트)들을 감싸는 root엘리먼트 :  <mapper namespace="">는 반드시 프로젝트 전체에서 유일한

   이름을 가져야한다. 파일명이 달라도 유일한 이름으로 설정된다.

 

4. SQL설정방법

   1) Select 관련 SQL은 <select>SQL문</select>

   2) Insert 관련 SQL은 <insert>SQL문</insert>

   3) update 관련 SQL은 <update>SQL문</update>

   4) 각 태그에는 id속성을 이용하여 구분할 수 있는데, 이또한 유일한 값으로 설정해야 한다.

       (HTML에서 id속성을 부여하듯이 부여하면 된다.)

   5) 자바 코드에서는 mapper의 namespace을 이용하여 각각 id에 접근하여 SQL문을 실행한다.

       다만, 실제 실행은 mybatis의 내장 메서드가 수행한다.

   6) 각 태그에서 반환타입을 설정할 경우, resultType 속성을 이용하여 지정할 수 있는데, resultType에 관한 설정은

       mybatis환경설정 파일에서 설정할 수 있다. ( resultType객체는  mybatis환경설정 파일 미리 설정을 해야한다.)

   7) 각 태그의 시작태크와 닫는 태그 사이에 SQL문을 작성하는데, 일반적으로 가독성 때문에 SQL문은 대문자를

       사용한다.

   8) 기존 SQL문과의 차이점

       예) 기존 SQL : update board set title=?, content=? where seq=?

             mapper : update board set title=#{title}, content=#{content} where seq=#{seq} 

             (HTML에서는 ${ }로 표시하였는데 mapper쪽에서는 #으로 표기한다.)

  ※주의사항: xml문서는 텍스트 기반으로 작성되기 때문에 특히 SQL문의 띄어쓰기 부분에 주의해서 작성해야 한다.※

 

 


 

*Mybatis환경설정*

 

 

1. myBatis의 DB연동

   ㄱ) myBatis의 DB연동을 처리하기 위해서는 반드시 DataSource가 필요하다.

   ㄴ) DataSource에 있어야 필수 정보 : 접속드라이버, 접속주소, 사용자계정, 비밀번호

       src/main/resources->file생성->db.properties-

        jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
        jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:XE
        jdbc.username=아이디
        jdbc.password=비밀번호

 

2. mybatis환경설정 파일 만들기

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>
	<!-- Properties 파일 설정 -->
	<properties resource="db.properties" />

	<!-- Alias 설정 -->
	<typeAliases>
		<typeAlias alias="board" type="com.jbr.biz.board.BoardVO" />
	</typeAliases>

	<!-- DataSource설정 -->
	<environments>
		<environment id="">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED"> <!--pooled란 connectionpool -->
				<property name="driver" value="${jdbc.driverClassName  }" /> <!--name속성 변경 불가/${}은 db.propertis에서 설정한 값 -->
				<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>

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

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

 

3. properties 파일 설정(어떤 파일을 사용할것인지!)

    <properties resource="프로퍼티스 파일명"></properties>

 

4. alias 설정(자동 매핑 객체 설정)

    <select id="getBoardList" resultType="board">
         select * from board where title like '%'||#{searchKeyword}||'%' order by seq desc
    </select>

    의 관련된 처리부분임

   <typeAliases>

        <typeAlias alias="객체명" type="클래스 풀네임(패키지구조.클래스)"/>

   </typeAliases>

 

5. DataSource설정(DataSource 객체 설정)

     <environments>

        <environment id="">

             <transactionManager type="JDBC" />

             <dataSource type="POOLED"> <!--pooled란 connectionpool -->

                 <property name="driver" value="${   }" /> <!--name속성 변경 불가/${}은 db.propertis에서 설정한 값-->

                 <property name="url"     value="${   }" />

                 <property name="username" value="${   }" />

                 <property name="password"  value="${   }" />         

             </dataSource>

        </environment>

     </environments>

 

6. SQL Mapper 설정 (SQL문 작성문서 : board-mapping.xml)

   <mappers>

       <mapper resouce="패키지명/xml문서">

   </mappers>

 

 

 


 

*SQLSession 객체생성하기*

 

 

*자바코드에서 SQLSession 객체를 생성하는순서

1. "sql-map-config.xml" 문서를 읽어야 한다.

    - Reader reader = Resource.getResourceAsReader("읽어들일 해당 XML문서")

 

2. 읽은 문서를 이용하여 SqlSessionFactory객체를 생성

    -SqlSessionFactory 변수명 = new SqlSessionFactoryBulider( ).build(Reader 객체);

 

3.  SqlSessionFactory 객체를 통하여 SqlSession 객체를 얻기(생성)

    -SqlSession  변수명 = SqlSessionFactory객체.openSession( );

 

4. SqlSession 객체 내부 주요 메서드

     1) insert("Mapper의 네임스페이스.해당id",  전달객체);

         예 ) insert("BoardDAO.insertBoard", BoardVO);

     2) update("Mapper의 네임스페이스.해당id",  전달객체);

         예 ) update("BoardDAO.insertBoard", BoardVO);

     3) delete("Mapper의 네임스페이스.해당id",  전달객체);

         예 ) delete("BoardDAO.insertBoard", BoardVO);

     4) select관련

         ㄱ)selectOne("Mapper의 네임스페이스.해당id",  전달객체);

             :검색된 레코드 중에 하나의 레코드 값만 반환

             예 ) selectOne("BoardDAO.insertBoard", BoardVO);

         ㄴ)selectList("Mapper의 네임스페이스.해당id",  전달객체); 

             :검색된 여러개의 레코드를 List타입으로 반환

             예 ) selectList("BoardDAO.insertBoard", BoardVO);

    5) commit( );

        실제 데이터베이스 수정을 확정하는 메서드

 

package com.jbr.biz.util;

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 SqlSessionFactoryBean {
	
	private static SqlSessionFactory sessionFactory =null;
	static{
		try{
			if(sessionFactory ==null){
				Reader reader =Resources.getResourceAsReader("sql-map-config.xml");
				sessionFactory= new SqlSessionFactoryBuilder().build(reader);
			}
		}catch(Exception e){
			System.err.println("SqlSessionFactory err:"+e.getMessage());
		}
	}
	
	public static SqlSession getSqlSessionInstance(){
		return sessionFactory.openSession();
	}
}

if(sessionFactory ==null){
Reader reader=Resources.getResourceAsReader("sql-map-config.xml");
sessionFactory= new SqlSessionFactoryBuilder().build(reader);

이 부분은 오타 조심하자!

 

 


 

*DAO클래스 작성*

 

mybatis를 이용하여 데이터베이스 연동을 처리하는 BoardDAO클래스이다.

package com.jbr.biz.board.impl;

import java.util.List;
import org.apache.ibatis.session.SqlSession;

import com.jbr.biz.board.BoardVO;
import com.jbr.biz.util.SqlSessionFactoryBean;

public class BoardDAO {
	private SqlSession mybatis;
	
	public BoardDAO() {
		mybatis=SqlSessionFactoryBean.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 getBoard(BoardVO vo){
		return (BoardVO) mybatis.selectOne("BoardDAO.getBoard", vo);
	}
	
	public List<BoardVO> getBoardList(BoardVO vo){
		return mybatis.selectList("BoardDAO.getBoardList",vo);
	}
	
}

※참고사항※

1. mybatis.insert("BoardDAO.insertBoard",vo);

    첫번째 인자값은 반드시문자열로 표기해야한다.

    그중에 BoardDAO부분은 mapper태크의 namespace의 id와 동일해야한다.

    또한insertBoard부분도  insertBoard의메서드명도 동일해야한다.

    물론 나머지들도 마찬가지이다.

2. mybatis.commit();

    변경사항이 있는 SQL문같은 경우 반드시 mybatis.commit(); 를 작성해주어서 변경사항을 저장해주어야한다.

    만약 mybatis.commit();을 누락할시 실제 데이터저장이나 변경 등등이 적용이 안된다.

 

*테스트 클라이언트 작성 및 실행*

 

package com.jbr.biz.board;

import java.sql.SQLException;
import java.util.List;

import com.jbr.biz.board.impl.BoardDAO;

public class BoardServiceClient {

	public static void main(String[] args) throws SQLException{
		BoardDAO boardDAO=new BoardDAO();
		
		BoardVO vo=new BoardVO();
		vo.setTitle("myBatis 제목");
		vo.setWriter("장보라");
		vo.setCotent("들을만하네욤");
		boardDAO.insertBoard(vo);
		
		vo.setSearchCondition("TITLE");
		vo.setSearchKeyword("");
		List<BoardVO> boardList=boardDAO.getBoardList(vo);
		for(BoardVO board : boardList){
			System.out.println("-->"+board.toString());
		}
	}
}

 

*Console 결과화면 *

 

// ibatis-core 라이브러리 => myBatis 프레임워크

14:19:56.380 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.

 

// PooledDataSource => <dataSource type="POOLED">

14:19:56.533 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.

14:19:56.533 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.

14:19:56.533 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.

14:19:56.533 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.

 

// BoardDAO.java => public void insertBoard(BoardVO vo) { System.out.println(vo.toString()); ~~}

BoardVO [seq=0, title=myBaits 제목, writer=홍길동, content=myBatis 내용입니다....., regDate=null, cnt=0, searchCondition=null, searchKeyword=null]

 

// sql-map-config.xml => <transactionManager type="JDBC" />

14:19:56.592 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection

 

// PooledDataSource => <dataSource type="POOLED">

14:19:56.937 [main] DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 1218593486.

 

//  JDBC Connection 와 <property name="driver" value="${jdbc.driverClassName}" />

14:19:56.937 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@48a242ce]

 

// BoardDAO.java => public void insertBoard(BoardVO vo) { ~~ mybatis.insert("BoardDAO.insertBoard", vo); }

// "BoardDAO.insertBoard" => board-mapping.xml  => <insert id="insertBoard">

14:19:56.938 [main] DEBUG BoardDAO.insertBoard - ==>  Preparing: insert into board (seq, title, writer, content) values ((select nvl(max(seq), 0)+1 from board),?,?,?) 

 

// BoardVO vo => myBaits 제목(String), 홍길동(String), myBatis 내용입니다.....(String)

14:19:57.014 [main] DEBUG BoardDAO.insertBoard - ==> Parameters: myBaits 제목(String), 홍길동(String), myBatis 내용입니다.....(String)

 

// BoardDAO.java => public void insertBoard(BoardVO vo) { ~~ mybatis.insert("BoardDAO.insertBoard", vo);  mybatis.commit(); }

14:19:57.018 [main] DEBUG BoardDAO.insertBoard - <==    Updates: 1

 

// 

14:19:57.018 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Committing JDBC Connection [oracle.jdbc.driver.T4CConnection@48a242ce]

 

//  BoardDAO.java => public List<BoardVO> getBoardList(BoardVO vo) { mybatis.selectList("BoardDAO.getBoardList", vo); }

// "BoardDAO.getBoardList" => board-mapping.xml  => <select id="getBoardList" resultType="board">

14:19:57.019 [main] DEBUG BoardDAO.getBoardList - ==>  Preparing: select * from board where title like '%'||?||'%'order by seq desc 

 

// vo.setSearchKeyword("");

14:19:57.019 [main] DEBUG BoardDAO.getBoardList - ==> Parameters: (String)

 

//  board-mapping.xml  => <select id="getBoardList" resultType="board">

// List<BoardVO> boardList = boardDAO.getBoardList(vo);

14:19:57.089 [main] DEBUG BoardDAO.getBoardList - <==      Total: 19

 

// for (BoardVO board : boardList) {

//     System.out.println("---> " + board.toString());

// }

---> BoardVO [seq=40, title=myBaits 제목, writer=홍길동, content=myBatis 내용입니다....., regDate=Tue Jun 29 14:19:57 KST 2021, cnt=0, searchCondition=null, searchKeyword=null]

---> BoardVO [seq=39, title=Mapper XML 제목, writer=Mapper, content=Mapper XML 내용입니다....., regDate=Mon Jun 28 16:52:33 KST 2021, cnt=0, searchCondition=null, searchKeyword=null]

---> BoardVO [seq=38, title=myBaits 제목, writer=홍길동, content=myBatis 내용입니다....., regDate=Mon Jun 28 16:48:26 KST 2021, cnt=0, searchCondition=null, searchKeyword=null]

---> BoardVO [seq=37, title=ㅂㅈㅂㅈ, writer=ㅂㅈㅂㅈ, content=ㅂㅈㅂㅈ, regDate=Mon Jun 28 12:04:03 KST 2021, cnt=0, searchCondition=null, searchKeyword=null]

 중략~~~

'Framework > Spring' 카테고리의 다른 글

Lombok  (0) 2021.07.01
Spring - mybatis(Mapper XML)  (0) 2021.06.29
Spring-MVC  (0) 2021.06.23
Spring-어노테이션 기반 MVC개발  (0) 2021.06.23
Spring-Transaction(트랜잭션)  (0) 2021.06.23
Comments