복습 ARCHIVE/모델별 프로젝트
[Spring] Mybatis 설치 및 간단한 사용
SummerON
2021. 6. 29. 14:24
Mybatis 설치 방법
Help > Eclipse Marketplace > Mybatis 1.2.4 설치!
설치 후 뉴 프로젝트 생성 시, Mybatis MyBatis XML Mapper가 보이는 지 확인!
Mybatis
- 한 두줄의 자바코드로 DB 연동을 처리
- SQL 명령어를 자바 코드에서 분리하여 XML 파일에 따로 관리 => SQL수정 시 XML만 바꾸면 되서 자바파일을 다시 컴파일 할 필요가 없음
- 반환타입을 XML에서 지정하기 때문에 자바를 통해 반환타입을 지정할 필요 없음
- 데이터 맵퍼 : XML에 저장된 SQL 명령어를 대신 실행하고 실행 결과를 VO와 같은 자바 객체에 자동을 맵핑해줌
프로젝트 생성
Spring Lagacy Project > Simple Project로 생성
properties > Project Facet에서 자바 버전 1.8 설정/ runtimes JDK 설정
properties > Build path > Library > External Library > ojdbc8.jar 외부 라이브러리로 추가
간단한 마이바티스 사용 예제
1. Dependency 추가 (pom.xml)
<properties>
<!-- Generic properties -->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<spring-framework.version>4.2.4.RELEASE</spring-framework.version>
<!-- Hibernate / JPA : 라이브러리 -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
</properties>
<!--중간 생략 --!>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency>
<!-- Ibatis -->
<dependency>
<groupId>org.apache.ibatis</groupId>
<artifactId>ibatis-core</artifactId>
<version>3.0</version>
pom.xml 저장 후 마이바티스, 아이바티스가 메이븐에 설치 되었는지 확인 !
2. VO 객체 만들기
src/main/java에 BoardVO 만들기
3. SQL Mapper XML 만들기
- src/main/resource/mappings
- new > other > Mybatis Mapper XML 로 생성
<!-- 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">
<!-- 전체 태그(엘리먼트)들을 감싸는 root 앨리먼트 mapper
"mappings.board-mapping"는 자바에서 사용할 이름으로 반드시 프로젝트 전체에서 유일한 이름으로 설정
-->
<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 from board where seq=#{seq}
</delete>
<select id="getBoard" resultType="board">
select * from board where seq=#{seq}
</select>
<select id="getBoardList" resultType="board">
select *from board where title like '%'||#{searchKeyword}||'%' order by seq desc
</select>
</mapper>
- 초기 설정 : SQL 을 다룰거면 도큐먼트 타입이 맵퍼로 잡혀 있어야 함
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <select>, <insert> , <update>등 태그를 통해 SQL 문 사용
- 각 태그에 id 속성을 이용하여 자바코드에서 접근 후 SQL문 실행 => 실행은 Mybatis 내장 메서드가 수행
- 각 태그에서 반환타입 설정 가능 , <resultType>속성 이용 (Mybatis 환경설정 파일)
- SQL 문 : update board set title=#{title} where seq=#{seq)
- XML은 텍스트 기반이기 때문에 sql문 띄어쓰기 및 스펠링 주의
4. Mybtis 환경설정 (sql-map-config.xml)
- DB연동을 위해 DataSource 필요 : 접속드라이버, 접속주소, 사용자계정, 비밀번호(db.properties에 저장)
- src/main/resource에 Mybatis Mapper XML파일로 sql-map-config.xml 생성
=> DataSource 정보위치 / VO 객체 설정 / DataSource 정보를 이용한 접속 객체 설정 / SQL mapper 설정
<?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"></properties>
<!-- Alias 설정 : 자동 맵핑 객체 설정 -->
<typeAliases>
<typeAlias type="com.hhw.biz.board.BoardVO" alias="board"/>
</typeAliases>
<!-- DataSource 설정 : JDBC사용, 커넥션풀 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<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(sql문 있는 곳) 설정 -->
<mappers>
<mapper resource="mapping/board-mapping.xml"/>
</mappers>
</configuration>
- 초기설정을 환경설정 파일 설정으로 변경
- <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
- alias : java 클래스 파일이기 때문에 패키지 위치 지정
- mapper : xml 파일이기 때문에 설정 파일 기준 상대위치와 확장자까지 지정
- 이 문서를 이용하여 실제로 일을 처리하는 SqlSession 객체 생성
5. SqlSession 객체 생성하기
세션의 메소드를 통해 DB작업함
SqlSession객체 생성 순서
- "sql-map-config.xml" 문서 읽기 : Reader reader =Reaource.getResourceAsReader("sql-map-config.xml")
- 읽은 문서를 이용하여 SqlSessionFactory 객체를 생성
- SqlSessionFactory 객체를 통하여 SqlSession 객체 생성
SqlSession 객체 내부 주요 메서드 (mapper namespace="BoardDAO" / insert id="insertBoard")
- insert("BoardDAO.insertBoard", BoardVO객체)
- selectOne("BoardDAO.getBoard", BoardVO객체) 등
- commit() - 실제 데이터베이스 수정을 확정하는 메서드
package com.hhw.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;
public SqlSessionFactoryBean() {
}
//static벼수에 대한 초기값 설정
static{
try{
if(sessionFactory == null){
Reader reader = Resources.getResourceAsReader("sql-map-config.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
}catch(Exception e){
System.out.println("SqlSessionFactory build ERR : "+ e.getMessage());
}
}//static end
//DAO 클래스에서 호출할 메서드
public static SqlSession getSqlSessionInstance(){
return sessionFactory.openSession();
}
}
6. DAO 클래스 작성
- SqlSessionFactoryBean을 이용하여 SqlSession 객체 생성
- SqlSession 객체의 메서드를 이용하여 CRUD기능 구현
- SqlSession 메소드는 두개의 파라미터를 받음 ("SQL id 정보" , parameterType속성으로 지정된 파라미터 객체)
- * SQL id 정보는 문자열로 SQL Mapper에 선언된 네임스페이스(BoardDAO)와 아이디(insertBaord)를 조합하여 지정
package com.hhw.biz.board.impl;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.hhw.biz.board.BoardVO;
import com.hhw.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 mybatis.selectOne("BoardDAO.getBoard",vo);
}
public List<BoardVO> getBoardList(BoardVO vo){
return mybatis.selectList("BoardDAO.getBoardList",vo);
}
}
7. 테스트 클라이언트 실행
src/test/java
package com.hhw.biz.board;
import java.sql.SQLException;
import java.util.List;
import com.hhw.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("마이바티스");
vo.setWriter("가가가");
vo.setContent("내용 설정하기");
boardDAO.insertBoard(vo);
vo.setSearchCondition("TITLE");
vo.setSearchKeyword("");
List<BoardVO> boardList = boardDAO.getBoardList(vo);
for(BoardVO board:boardList){
System.out.println("------>" +board.toString());
}
}
}
실행결과
14:21:31.611 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
14:21:32.138 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
14:21:32.138 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
14:21:32.139 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
14:21:32.139 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
14:21:32.290 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
14:21:36.410 [main] DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 1411892748.
14:21:36.410 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@5427c60c]
14:21:36.413 [main] DEBUG BoardDAO.insertBoard - ==> Preparing: insert into board (seq, title, writer, content) values ((select nvl(max(seq), 0)+1 from board), ?, ?, ?)
14:21:36.663 [main] DEBUG BoardDAO.insertBoard - ==> Parameters: 마이바티스(String), 가가가(String), 내용 설정하기(String)
14:21:36.675 [main] DEBUG BoardDAO.insertBoard - <== Updates: 1
14:21:36.675 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Committing JDBC Connection [oracle.jdbc.driver.T4CConnection@5427c60c]
14:21:36.682 [main] DEBUG BoardDAO.getBoardList - ==> Preparing: select *from board where title like '%'||?||'%' order by seq desc
14:21:36.683 [main] DEBUG BoardDAO.getBoardList - ==> Parameters: (String)
14:21:36.885 [main] DEBUG BoardDAO.getBoardList - <== Total: 20
------>BoardVO [seq=28, title=마이바티스, writer=가가가, content=내용 설정하기, regDate=Tue Jun 29 14:21:36 KST 2021, cnt=0]
------>BoardVO [seq=27, title=마이바티스, writer=가가가, content=내용 설정하기, regDate=Tue Jun 29 14:19:12 KST 2021, cnt=0]
------>BoardVO [seq=26, title=마이바티스, writer=가가가, content=내용 설정하기, regDate=Tue Jun 29 14:18:38 KST 2021, cnt=0]
------>BoardVO [seq=25, title=ㅇㅇdd, writer=ㅇㅇㅇㅇ, content=null, regDate=Wed Jun 23 11:53:43 KST 2021, cnt=0]
------>BoardVO [seq=23, title=새글 등록, writer=새글, content=null, regDate=Mon Jun 21 14:04:21 KST 2021, cnt=0]
------>BoardVO [seq=20, title=어노테이션, writer=all, content=all, regDate=Fri Jun 18 13:56:13 KST 2021, cnt=0]
------>BoardVO [seq=19, title=어라운드, writer=all, content=con, regDate=Fri Jun 18 11:21:42 KST 2021, cnt=0]
------>BoardVO [seq=17, title=조인포인트fffffㅌ, writer=all, content=null, regDate=Fri Jun 18 10:57:21 KST 2021, cnt=0]
------>BoardVO [seq=16, title=조인포인트, writer=all, content=contents, regDate=Fri Jun 18 10:45:18 KST 2021, cnt=0]
------>BoardVO [seq=15, title=어라운드 yyyyy, writer=all, content=null, regDate=Fri Jun 18 10:18:24 KST 2021, cnt=0]
------>BoardVO [seq=14, title=예외인데.., writer=get, content=contents, regDate=Fri Jun 18 10:08:04 KST 2021, cnt=0]
------>BoardVO [seq=12, title=advice get, writer=get, content=contents, regDate=Fri Jun 18 09:55:03 KST 2021, cnt=0]
------>BoardVO [seq=10, title=afterfirst, writer=gettest, content=contents, regDate=Thu Jun 17 14:59:28 KST 2021, cnt=0]
------>BoardVO [seq=8, title=getfirst, writer=gettest, content=contents, regDate=Thu Jun 17 14:51:30 KST 2021, cnt=0]
------>BoardVO [seq=7, title=first, writer=test, content=contents, regDate=Thu Jun 17 14:36:04 KST 2021, cnt=0]
------>BoardVO [seq=5, title=ffff 제목3, writer=테스트2, content=테스트 내용2, regDate=Thu Jun 17 12:24:40 KST 2021, cnt=0]
------>BoardVO [seq=4, title=0617 제목3, writer=테스트2, content=테스트 내용2, regDate=Thu Jun 17 11:44:27 KST 2021, cnt=0]
------>BoardVO [seq=3, title=0617 제목2, writer=테스트2, content=테스트 내용2, regDate=Thu Jun 17 11:37:21 KST 2021, cnt=0]
------>BoardVO [seq=2, title=테스트용 제목2, writer=테스트2, content=테스트 내용2, regDate=Wed Jun 16 17:42:49 KST 2021, cnt=0]
------>BoardVO [seq=1, title=테스트용 제목, writer=테스트, content=테스트 내용, regDate=Wed Jun 16 17:40:21 KST 2021, cnt=0]