능글맞은 구렁이
Spring-Mybatis 본문
*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 |