JAVA/개념정리
Ibatis
inderrom
2022. 12. 6. 01:11
iBatis란
- JAVA에서 DB를 편하게 핸들링할 수 있게 해주는 프레임워크이다.
- SQL문과 Java소스코드를 분리하고, 파라미터 값만 같으면 Java소스코드 변경 없이
사용할 수 있다.
- iBatis 데이터 매퍼 API를 사용해서 자바빈즈(보통 VO객체)혹은 Map객체를
PreparedStatement의 파라미터에 매핑 해주고 SQL문의 실행 결과를
자바빈즈 혹은 Map객체에 자동으로 매핑해준다.
1. SqlMqpConfig 설정 - mxl 문서
<?xml version="1.0" encoding="UTF-8"?>
<!-- 이 문서는 iBatis의 환경 설정 내용을 가지고 있는 xml문서 -->
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD DQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!--
DB와 연결하는 정보를 .properties파일에 저장해 놓고
이 .properties파일의 내용을 읽어 올 수 있도록 설정한다.
-->
<properties resource="kr/or/ddit/ibatis/config/dbinfo.properties"/>
<!--
각각의 sqlMap파일의 namespace 속성값과 id 속성값을 연결해서
실행할 SQL문을 선택할 수 있게 한다.
-->
<settings useStatementNamespaces="true"/>
<!--
SQL문에 사용할 VO객체는 패키지 이름을 포함한 전체 이름을 사용해야 한다.
그렇게 되면 문장이 너무 길어질 수 있기 때문에 이 전체 이름을 대신해서 사용할
alias를 설정할 수 있다.
형식) <typeAlias alias="사용할alias명" type="사용할 클래스의 전체이름"/>
-->
<typeAlias alias="lprodVo" type="kr.or.ddit.vo.LprodVO"/>
<!--
DB와의 연결을 처리하는 부분
-->
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${user}"/>
<property name="JDBC.Password" value="${pass}"/>
</dataSource>
</transactionManager>
<!--
실행할 SQL문 등록하기
==> 실행할 SQL문은 xml문서로 따로 만든 후 그 xml문서를 아래와 같이 등록하면 된다.
형식) <sqlMap resource="경로명/파일명.xml"/>
-->
<sqlMap resource="kr/or/ddit/ibatis/mapper/lprodTest-mapper.xml"/>
</sqlMapConfig>
2. VO 객체 생성 ( src에 vo패키지에 생성한다)
package kr.or.ddit.vo;
public class LprodVO {
private int lprod_id;
private String lprod_gu;
private String lprod_nm;
public int getLprod_id() {
return lprod_id;
}
public void setLprod_id(int lprod_id) {
this.lprod_id = lprod_id;
}
public String getLprod_gu() {
return lprod_gu;
}
public void setLprod_gu(String lprod_gu) {
this.lprod_gu = lprod_gu;
}
public String getLprod_nm() {
return lprod_nm;
}
public void setLprod_nm(String lprod_nm) {
this.lprod_nm = lprod_nm;
}
}
3. mapper 작성
<?xml version="1.0" encoding="UTF-8"?>
<!-- 이 문서는 iBatis에서 처리할 SQL문을 작성하는 문서입니다. -->
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org/DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="lprod">
<!--
이 영역에는 처리할 SQL문에 맞는 태그를 사용해서 SQL문을 작성한다.
사용할 수 있는 기본적인 태그들... (이것말고도 여러개 있음)
<select> 처리할 select문 </select>
<insert> 처리할 insert문 </insert>
<delete> 처리할 delete문 </delete>
<update> 처리할 update문 </update>
...
-->
<!--
id속성 ==> 실행할 태그를 Java 소스에서 호출할 때 사용되는 이름으로
<sqlMap>태그의 namespace 속성값과 연결해서 사용한다.
(예: 'lprod.insertLprod')
parameterClass속성 ==> SQL문에 사용될 데이터가 저장된 객체를 기술한다.
(보통 VO클래스, 또는 Java의 기본 자료형이름, Map객체 등이 사용된다.
<VO클래스 등을 기술할 때는 해당 클래스의 전체 이름을 기술하거나 등록된 alias명을 기술한다.)
preparedStatement에서 사용했던 ? 대신 VO 객체의 변수명을 ## 사이에 작성한다.
#변수명#
-->
<insert id="insertLprod" parameterClass="kr.or.ddit.vo.LprodVO">
insert into lprod(lprod_id, lprod_gu, lprod_nm)
values(#lprod_id#, #lprod_gu#, #lprod_nm#)
</insert>
<!-- parameterClass속성에 <typeAlias>에 등록한 alias명을 사용할 수 있다. -->
<update id="updateLprod" parameterClass="lprodVo">
update lprod set lprod_id=#lprod_id#, lprod_nm=#lprod_nm#
where lprod_gu=#lprod_gu#
</update>
<!--
parameterClass속성에 설정되는 값이 단일 값이면
SQL문에 이 값을 나타내는 변수명은 특별히 이름이 정해지지 않는다.
(즉, 사용자 임의로 지정할 수 있다.)
(단일값이면 parameterClass에 java의 기본 자료형 이름을 쓸 수 있다.)
-->
<delete id="deleteLprod" parameterClass="string">
delete from lprod where lprod_gu=#lprod_gu#
<!-- delete from lprod where lprod_gu=#asdf# << 이렇게도 된다-->
</delete>
<!--
resultClass ==> select문을 처리할 때 반드시 지정하는 속성으로 select문의 처리 결과를 저장 할
VO클래스나 Map클래스, 그리고 자바의 기본 자료형이름을 지정한다.
select문을 처리한 결과가 1개 또는 여러개여도 이 속성에 설정하는 것은
1개의 레코드가 저장될 클래스나 자료형 이름을 지정하면 된다.
( 이유 : 결과가 여러개일 경우에는 iBatis에서 자동으로 List에 담아 줄 수 있다.)
-->
<select id="getAllLprod" resultClass="lprodVo">
select * from lprod
</select>
<select id="getLprod" parameterClass="string" resultClass="lprodVo">
select * from lprod where lprod_gu =#lprod_gu#
</select>
</sqlMap>
4. 실행하기
package kr.or.ddit.basic;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.util.List;
import java.util.Scanner;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import kr.or.ddit.vo.LprodVO;
public class LprodIbatisTest {
// iBatis를 이용하여 DB자료를 처리하는 방법 및 순서
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
SqlMapClient smc = null;
// 1. iBatis의 환경 설정 파일을 읽어와서 실행한다. (sqlMapConfig.xml)
try {
// 1-1 문자 인코딩 캐릭터셋 설정
Charset charset = Charset.forName("UTF-8");
Resources.setCharset(charset);
// 1-2. 환경 설정 파일 읽기
Reader rd =
Resources.getResourceAsReader("kr/or/ddit/ibatis/config/sqlMapConfig.xml");
// 1-3. 위에서 읽어온 Reader객체를 이용하여 실제 환경 설정을 완성한 후에
// SQL문을 호출해서 실행할 수 있는 객체를 생성한다.
smc = SqlMapClientBuilder.buildSqlMapClient(rd);
rd.close(); // Reader객체 닫기
} catch (Exception e) {
System.out.println("iBatis 환경 설정 오류 ....");
e.printStackTrace();
}
//--------------------------------------------------------------
// 2. 실행할 SQL문에 맞는 쿼리문을 호출해서 원하는 작업을 수행한다.
try {
/*
// 2-1. insert연습
System.out.println("insert 작업 시작...");
System.out.println("Lprod_id 입력 >> ");
int num = scan.nextInt();
System.out.println("Lprod_gu 입력 >> ");
String gu = scan.next();
System.out.println("Lprod_nm 입력 >> ");
String nm = scan.next();
// 1) 입력 받은 자료를 VO객체에 저장한다.
LprodVO lvo = new LprodVO();
lvo.setLprod_id(num);
lvo.setLprod_gu(gu);
lvo.setLprod_nm(nm);
// 2) sqlMapClient객체 변수(smc)를 이용하여 처리할 SQL문을 호출하여 실행한다.
// 형식) smc.insert("namespace속성값.id속성값", 파라미터클래스)
// ==> 반환값 : insert성공 : null, insert실패 : 오류객체 << 숫자가 중요한 게 아니라 ~Exception 때문에 Object를 써준다.
Object obj = smc.insert("lprod.insertLprod", lvo);
if(obj==null) {
System.out.println("insert 작업 성공!!!");
}else {
System.out.println("insert 작업 실패~~~");
}
System.out.println("--------------------------------------------");
*/
/*
// 2-2. update연습
System.out.println("update 시작...");
System.out.print("수정할 Lprod_gu 입력 >>");
String lgu = scan.next();
System.out.print("새로운 Lprod_id 입력 >>");
int lid= scan.nextInt();
System.out.print("새로운 Lprod_nm 입력 >>");
String lnm= scan.next();
// 1) 입력 받은 자료를 VO객체에 저장한다.
LprodVO lvo2 = new LprodVO();
lvo2.setLprod_id(lid);
lvo2.setLprod_gu(lgu);
lvo2.setLprod_nm(lnm);
// 2) 쿼리문 실행하기
// 형식) smc.update("namespace속성값.id속성값", 파라미터클래스)
// ==> 반환값 : 작업에 성공한 레코드 수
int cnt = smc.update("lprod.updateLprod", lvo2);
if(cnt>0) {
System.out.println("update 작업 성공!!!");
}else {
System.out.println("update 작업 실패~~");
}
System.out.println("--------------------------------------------");
*/
/*
// 2-3. delete연습
System.out.println("delete 작업 연습...");
System.out.print("삭제할 Lprod_gu 입력 >> ");
String lgu2 = scan.next();
// 1) 쿼리문 실행하기
// 형식) smc.delete("namespace속성값.id속성값", 파라미터클래스)
// ==> 반환값 : 작업에 성공한 레코드 수
int cnt2 = smc.delete("lprod.deleteLprod", lgu2);
if(cnt2>0) {
System.out.println("delete 작업 성공!!!");
}else {
System.out.println("delete 작업 실패~~~");
}
System.out.println("--------------------------------------------");
*/
/*
// 2-4. select연습
// 1) select한 결과가 여러개인 경우
System.out.println("select 연습 시작 (결과가 여러개일 경우)...");
// select한 결과가 여러개일 경우에는 queryForList()메서드를 사용하는 데
// 이 메서드는 여러개의 레코드 각각을 VO에 담은 후 이 VO객체를 List에 추가해 주는
// 작업을 자동으로 수행한다.
// 형식) smc.queryForList("namespace속성값.id속성값", 파라미터클래스)
// 반환값 ==> 데이터가 저장된 List객체
List<LprodVO> lprodList = smc.queryForList("lprod.getAllLprod");
for(LprodVO lvo3 : lprodList) {
System.out.println("Lprod_id : " + lvo3.getLprod_id());
System.out.println("Lprod_gu : " + lvo3.getLprod_gu());
System.out.println("Lprod_nm : " + lvo3.getLprod_nm());
System.out.println("------------------------------------");
}
System.out.println("출력 끝...");
System.out.println("====================================");
*/
// 2) select한 결과가 1개일 경우
System.out.println("select 연습 시작(결과가 1개일 경우)...");
System.out.print("검색할 Lprod_gu 입력 >> ");
String lgu3 = scan.next();
// select한 결과가 1개일 경우에는 queryForObject()메서드를 사용한다.
// 형식) smc.queryForObject("namespace속성값.id속성값", 파라미터클래스)
// 반환값 : 1) 쿼리문의 결과가 여러개일 경우 ==> Exception객체
// 2) 쿼리문의 결과가 1개일 경우 ==> 검색한 객체 (정상)
// 3) 쿼리문의 결과가 없을 경우 ==> null
// object라 형변환을 해줘야한다.
LprodVO lprodVo = (LprodVO)smc.queryForObject("lprod.getLprod", lgu3);
if(lprodVo==null) {
System.out.println("검색한 결과가 하나도 없습니다...");
return;
}
System.out.println("-- 검색 결과 --");
System.out.println("Lprod_id : " + lprodVo.getLprod_id());
System.out.println("Lprod_gu : " + lprodVo.getLprod_gu());
System.out.println("Lprod_nm : " + lprodVo.getLprod_nm());
System.out.println("------------------------------------");
} catch (SQLException e) {
e.printStackTrace();
}
}
}