Ibatis

서현서현·2022년 4월 21일
1

서블릿 & JSP

목록 보기
3/26
post-thumbnail

iBatis

  • DB의 자원을 보다 편리하게 가져온다
  • 사용자 대신 JDBC 코딩을 해주는 역할!
  • 프로그램 소스코드에서 SQL문장을 분리하여 별도의 XML파일로 저장해 연결

ibatis 연습

sqlMapConfig

+) 사용할 sql문은 xml문서로 만들어놓고 sqlMap resource로 연결해 사용한다!

+) properties 파일 내용으로, sqlMapConfig와 매핑된다.

연결정보

아이바티스의 설정정보를 여기에 세팅하다.

member.xml

  • DAO에서 호출할 sql 쿼리를 작성한다.
  • 작성법에 맞춰서 작성해야한다.
💡 1) id속성 : 해당태그를 호출할 때 태그의 namespace와 연결하여 사용하는 이름

2) parameterClass 속성 : sql문에 사용할 데이터가 들어있는 객체타입을 지정한다
(보통 VO클래스, 자바의 자료형이름 등이 사용된다)
(typeAlias로 지정한 alias명을 사용할 수 잇다)

3) resultClass 속성 : select문을 실행한 결과를 담을 객체를 지정한다.
(보통 VO클래스나 자바의 자료형이름을 사용한다.)
(typeAlias로 지정한 alias명을 사용할 수 있다)

4) resultMap 속성 : 결과 레코드 컬럼명과 VO객체의 property명이 다를 경우에 적절한 매핑을 위해 사용한다

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
			PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
			"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="memberTest">
	
<!--  
	이 영역에 sql문에 맞는 태그를 사용하여 SQL문을 기술한다.
	
	사용 할 수 있는 기본적인 태그들
	 <select> ~~~ </select>
	 <insert> ~~~ </insert>
	 <update> ~~~ </update>
	 <delete> ~~~ </delete>
	 
	 위 태그에서 사용되는 속성들
	 1) id속성 : 해당태그를 호출할 때 <sqlMap>태그의 namespace와 연결하여 사용하는 이름
	 2) parameterClass 속성 : sql문에 사용할 데이터가 들어있는 객체타입을 지정한다
	 					(보통 VO클래스, 자바의 자료형이름 등이 사용된다)
	 					(typeAlias로 지정한 alias명을 사용할 수 잇다)
	 3) resultClass 속성 : select문을 실행한 결과를 담을 객체를 지정한다.
	 					(보통 VO클래스나 자바의 자료형이름을 사용한다.)
	 					(typeAlias로 지정한 alias명을 사용할 수 잇다)
	 4) resultMap 속성 : 결과 레코드 컬럼명과 VO객체의 property명이 다를 경우에 적절한 매핑을 위해 사용한다
	 
 -->

	<insert id="insertMember" parameterClass="kr.or.ddit.member.vo.MemberVO">
	
		insert into mymember
		(mem_id,mem_name, mem_tel, mem_addr)
		values(#memId#,#memName#,#memTel#,#memAddr#)
	
	</insert>
	
	<update id="updateMember" parameterClass="memVO">
		update mymember
				set mem_name = #memName#,
					mem_tel = #memTel#,
					mem_addr = #memAddr#
				where mem_id = #memId#
	</update>
	
	
	<delete id="deleteMember" parameterClass="String">
		delete from mymember
		where mem_id = #memId#
	</delete>
	
	
</sqlMap>

MemberVO

// DB테이블에 있는 컬럼을 기준으로 데이터를 객체화한 클래스이다
/*
 
 	DB테이블의 '컬럼'이 이클래스의 '멤버변수'가 된다
 	DB테이블의 컬럼과 클래스의 멤버변수를 매핑하는 역할을 수행한다
 
 
 */

public class MemberVO {
	
	private String memId;
	private String memName;
	private String memTel;
	private String memAddr;
	
	public String getMemId() {
		return memId;
	}
	public void setMemId(String memId) {
		this.memId = memId;
	}
	public String getMemName() {
		return memName;
	}
	public void setMemName(String memName) {
		this.memName = memName;
	}
	public String getMemTel() {
		return memTel;
	}
	public void setMemTel(String memTel) {
		this.memTel = memTel;
	}
	public String getMemAddr() {
		return memAddr;
	}
	public void setMemAddr(String memAddr) {
		this.memAddr = memAddr;
	}
	
	
	@Override
	public String toString() {
		return "MemberVO [memId=" + memId + ", memName=" + memName + ", memTel=" + memTel + ", memAddr=" + memAddr
				+ "]";
	}
	
	
	
}

MemberIbatisTest

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.SQLException;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import kr.or.ddit.member.vo.MemberVO;

public class memberIbatisTest {
	public static void main(String[] args) {
		//iBatis를 이용하여 DB자료를 처리하는 작업순서
		// 1.iBatis의 환경설정파일을 읽어와 실행시킨다
		try {
			// 1-1. xml 문서 읽어오기
			Charset charset = Charset.forName("UTF-8"); //설정파일 인코딩 정보 설정
			Resources.setCharset(charset);
			Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
			
			// 1-2. 위에서 읽어온 Reader객체를 이용하여 실제 작업을 진행할 객체 생성
			SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);
			rd.close(); // Reader객체 닫기
			
			/////////////////////////////////////////////////////////////////
			
			// 2. 실행할 SQL문에 맞는 쿼리문을 호출해서 원하는 작업을 수행한다.
//			System.out.println("insert 작업 시작...");
//			
//			// 1) 저장할 데이터를 VO에 담는다
//			MemberVO mv = new MemberVO();
//			mv.setMemId("d001");
//			mv.setMemName("강감찬");
//			mv.setMemTel("010-3333-3333");
//			mv.setMemAddr("경남 사천시");
//			
//			// 2) SqlMapCient객체 변수를 이용하여 해당 쿼리문을 실행한다
//			//	형식) smc.insert("namespace값,id값", 파라미터객체);
//			//		반환값 : 성공하면 null이 반환된다
//			Object obj = smc.insert("memberTest.insertMember",mv);
//			if(obj==null) {
//				System.out.println("insert 성공");
//			}else {
//				System.out.println("insert 실패");
//			}
//			
			System.out.println("---------------------------------------");
			
			// 2-2. update 작업연습
			System.out.println("update 작업 시작...");
			
			MemberVO mv2 = new MemberVO();
			mv2.setMemId("d001");
			mv2.setMemName("이순신");
			mv2.setMemTel("1111-2222");
			mv2.setMemAddr("대전시 중구 대흥동");
			
			// update()의 반환값은 성공한 레코드수이다
			int cnt = smc.update("memberTest.updateMember",mv2);
			if(cnt>0) {
				System.out.println("update작업 성공");				
			}else {
				System.out.println("update작업 실패");
			}
			System.out.println("---------------------------------------");
			
			
			
			
			// 2-3. delete 연습
			System.out.println("delete 작업 시작..");
			
			// delete() 메소드의 반환값 : 성공한 레코드수
			
			int cnt2 = smc.delete("memberTest.deleteMember","d001");
			
			if(cnt2 > 0) {
				System.out.println("delete 성공");
			}else {
				System.out.println("delete 실패");
			}
		}catch(IOException e){
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

자주 볼 수 있는 에러

Exception in thread "main" com.ibatis.sqlmap.client.SqlMapException: There is no statement named memberTest.updateMember in this SqlMap.
	at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.getMappedStatement(SqlMapExecutorDelegate.java:231)
	at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(SqlMapExecutorDelegate.java:448)
	at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(SqlMapSessionImpl.java:90)
	at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.update(SqlMapClientImpl.java:66)
	at kr.or.ddit.basic.memberIbatisTest.main(memberIbatisTest.java:62)
  1. 스펠링틀렸거나
  2. XML 파일에 해당 아이디의 쿼리를 작성안했거나
  3. 아이디를 못찾았을때

+) insert작업시 cnt값으로 작업확인하기

위의 예제에서는 insert쿼리를 실행해 obj가 null이면 작업완료라고 했는데,

다른 작업들과 마찬가지로 int cnt로 확인하기 위해 코드를 바꿔보려고 한다.

⇒ update로 바꿔서 실행해주면 간단하게 가능하다!

⇒ 그럼에도 select라는 element를 만들어서 시퀀스를 xml에서 select도 하고insert로 해야 돼서 obj를 리턴하기 위해 필요하다.

// 2. 실행할 SQL문에 맞는 쿼리문을 호출해서 원하는 작업을 수행한다.
			System.out.println("insert 작업 시작...");
			
			// 1) 저장할 데이터를 VO에 담는다
			MemberVO mv = new MemberVO();
			mv.setMemId("d004");
			mv.setMemName("최지희");
			mv.setMemTel("010-3323-3333");
			mv.setMemAddr("경남 사천시");
			
//			 2) SqlMapCient객체 변수를 이용하여 해당 쿼리문을 실행한다
//				형식) smc.insert("namespace값,id값", 파라미터객체);
//					반환값 : 성공하면 null이 반환된다
//			Object obj = smc.insert("memberTest.insertMember",mv);
//			if(obj==null) {
//				System.out.println("insert 성공");
//			}else {
//				System.out.println("insert 실패");
//			}
			
			// 쿼리 자체는 insertMember를 사용하나, update메소드를 사용하여 int값을 받아 올 수 있도록 한다
			int cnt3 = smc.update("memberTest.insertMember",mv);
			if(cnt3>0) {
				System.out.println("insert작업 성공");				
			}else {
				System.out.println("insert작업 실패");
			}
			
			
			System.out.println("---------------------------------------");

Select

  • 만드는 방법이 조금 다르다!

결과가 여러개일경우

queryForList

//2-4. select연습
			// 1) 응답 결과가 여러개일 경우
			// 2) 응답 결과가 1개일 경우
			System.out.println("결과가 여러개일경우");
			
//			 응답 결과가 여러개일 경우에는 queryForList()를 사용한다.
//			 이 메서드는 여러개의 레코드를 VO에 담은 후 이 VO데이터를
//			 List에 추가해주는 작업을 자동으로 수행한다
			List<MemberVO> memList = smc.queryForList("memberTest.getMemberAll");
			
			for(MemberVO mv3 : memList) {
				System.out.println("ID : "+mv3.getMemId());
				System.out.println("이름 : "+mv3.getMemName());
				System.out.println("전화 : "+mv3.getMemTel());
				System.out.println("주소 : "+mv3.getMemAddr());
				System.out.println("================================");
			}
			
			System.out.println("출력끝");

xml 작성하는 두가지 방법

<select id="getMemberAll" resultClass="memVO">
	<!-- VO의 메소드에 적절히  매핑하기위해 sql문이 만드는 가상테이블의 컬럼명을 변경 -->
		 select mem_id as memId,
				mem_name as memName, 
				mem_tel as memTel, 
				mem_addr as memAddr 
		   from mymember
		
	</select>
<resultMap class="memVO" id="memMap">
		<result property="memId" column="mem_id"/>
		<result property="memName" column="mem_name"/>
		<result property="memTel" column="mem_tel"/>
		<result property="memAddr" column="mem_addr"/>
	</resultMap>
	
	
	<select id="getMemberAll" resultMap="memMap">
	<!--  VO의 메소드에 적절히  매핑하기위해 sql문이 만드는 가상테이블의 컬럼명을 변경-->
		 select *
		   from mymember
		
	</select>

결과가 한개일 경우

// 2) 응답결과가 1개일경우
			System.out.println("select 연습 시작(결과가1개)....");
			
			// 응답결과가 1개가 확실한 경우에는 queryForObject 메서드를 사용
			MemberVO mv4 =
					(MemberVO) smc.queryForObject("memberTest.getMember","d002");
			
			System.out.println("ID : "+mv4.getMemId());
			System.out.println("이름 : "+mv4.getMemName());
			System.out.println("전화 : "+mv4.getMemTel());
			System.out.println("주소 : "+mv4.getMemAddr());
			System.out.println("================================");
<select id="getMember" parameterClass="String" resultMap="memMap">
		select *
		from mymember
		where mem_id = #memId#	
	</select>

ibatis 실습 << 코드 수정 필요!

Untitled

memberIbatisTest

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.SQLException;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import kr.or.ddit.member.vo.MemberVO;

public class memberIbatisTest {
	public static void main(String[] args) {
		//iBatis를 이용하여 DB자료를 처리하는 작업순서
		// 1.iBatis의 환경설정파일을 읽어와 실행시킨다
		try {
			// 1-1. xml 문서 읽어오기
			Charset charset = Charset.forName("UTF-8"); //설정파일 인코딩 정보 설정
			Resources.setCharset(charset);
			Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
			
			// 1-2. 위에서 읽어온 Reader객체를 이용하여 실제 작업을 진행할 객체 생성
			SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);
			rd.close(); // Reader객체 닫기
			
			/////////////////////////////////////////////////////////////////
			
			// 2. 실행할 SQL문에 맞는 쿼리문을 호출해서 원하는 작업을 수행한다.
/*			System.out.println("insert 작업 시작...");
			
			// 1) 저장할 데이터를 VO에 담는다
			MemberVO mv = new MemberVO();
			mv.setMemId("d004");
			mv.setMemName("최지희");
			mv.setMemTel("010-3323-3333");
			mv.setMemAddr("경남 사천시");
			
//			 2) SqlMapCient객체 변수를 이용하여 해당 쿼리문을 실행한다
//				형식) smc.insert("namespace값,id값", 파라미터객체);
//					반환값 : 성공하면 null이 반환된다
//			Object obj = smc.insert("memberTest.insertMember",mv);
//			if(obj==null) {
//				System.out.println("insert 성공");
//			}else {
//				System.out.println("insert 실패");
//			}
			
			// 쿼리 자체는 insertMember를 사용하나, update메소드를 사용하여 int값을 받아 올 수 있도록 한다
			int cnt3 = smc.update("memberTest.insertMember",mv);
			if(cnt3>0) {
				System.out.println("insert작업 성공");				
			}else {
				System.out.println("insert작업 실패");
			}
			*/
			
			System.out.println("---------------------------------------");
			
			
			// 2-2. update 작업연습
			System.out.println("update 작업 시작...");
			
			MemberVO mv2 = new MemberVO();
			mv2.setMemId("d001");
			mv2.setMemName("이순신");
			mv2.setMemTel("1111-2222");
			mv2.setMemAddr("대전시 중구 대흥동");
			
			// update()의 반환값은 성공한 레코드수이다
			int cnt = smc.update("memberTest.updateMember",mv2);
			if(cnt>0) {
				System.out.println("update작업 성공");				
			}else {
				System.out.println("update작업 실패");
			}
			System.out.println("---------------------------------------");
			
			
			
			
			// 2-3. delete 연습
			System.out.println("delete 작업 시작..");
			
			// delete() 메소드의 반환값 : 성공한 레코드수
			
			int cnt2 = smc.delete("memberTest.deleteMember","kl");
			
			if(cnt2 > 0) {
				System.out.println("delete 성공");
			}else {
				System.out.println("delete 실패");
			}
			
			
			//--------------------------------------------------
			
/*			//2-4. select연습
			// 1) 응답 결과가 여러개일 경우
			// 2) 응답 결과가 1개일 경우
			System.out.println("결과가 여러개일경우");
			
//			 응답 결과가 여러개일 경우에는 queryForList()를 사용한다.
//			 이 메서드는 여러개의 레코드를 VO에 담은 후 이 VO데이터를
//			 List에 추가해주는 작업을 자동으로 수행한다
			List<MemberVO> memList = smc.queryForList("memberTest.getMemberAll");
			
			for(MemberVO mv3 : memList) {
				System.out.println("ID : "+mv3.getMemId());
				System.out.println("이름 : "+mv3.getMemName());
				System.out.println("전화 : "+mv3.getMemTel());
				System.out.println("주소 : "+mv3.getMemAddr());
				System.out.println("================================");
			}
			
			System.out.println("출력끝");
			*/
			
			
			
			// 2) 응답결과가 1개일경우
			System.out.println("select 연습 시작(결과가1개)....");
			
			// 응답결과가 1개가 확실한 경우에는 queryForObject 메서드를 사용
			MemberVO mv4 =
					(MemberVO) smc.queryForObject("memberTest.getMember","d002");
			
			System.out.println("ID : "+mv4.getMemId());
			System.out.println("이름 : "+mv4.getMemName());
			System.out.println("전화 : "+mv4.getMemTel());
			System.out.println("주소 : "+mv4.getMemAddr());
			System.out.println("================================");

			
			
			
		}catch(IOException e){
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

IMemberDAO

import java.util.List;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.or.ddit.member.vo.MemberVO;

// 실제 DB와 연결해서 SQL문을 수행하여 결과를 작성하여 Service에 전달하는 DAO의 Interface

public interface IMemberDAO {
	
	
	//public int insertMember();
	// 여기 매개변수로 String name, String 어쩌구 ... 주면 나중에 유지보수가 귀찮을것같아 => VO를 만들자!
	
	
	
	// MemberVO에 감겨진 자료를 DB에 insert하는 메소드
	// @param mv DB에 insert할 자료가 저장된 MemberVO객체
	// @return DB작업이 성공하며 1이상의 값이 반환되고 실패하면 0이 반환된다
	public int insertMember(SqlMapClient smc, MemberVO mv);
	
	
	
	/*
		하나의 MemberVO 객체를 받아서 DB에 update하는메서드
		@param mv update할 회원정보가 들어있는 MemberVO객체
		@return 작업성공:1, 작업실패:0
	  
	*/
	public int updateMember(SqlMapClient smc,MemberVO mv);

	
	
	/*
		회원Id를 매개변수로 받아서 그 회원정보를 삭제하는 메서드
		 @param memId 삭제할 회원ID
		 @return 작업성공:1, 작업실패:0
	*/
	public int deleteMember(SqlMapClient smc,String memId);
	
	
	
	/*
		DB의 mymember테이블에 있는 전체레코드를 가져와서 List에 담아 반환하는 메서드
		@return MemberVO객체를 담고있는 List객체
	*/
	public List<MemberVO> getAllMemberList(SqlMapClient smc);
	
	
	
	/*
		주어진 회원ID가 존재하는지 여부를 알아내는 메소드
		@param memId 검색할 회원ID
		@return 해당회원ID가 있으면 true, 없으면 false
	
	*/
	public boolean checkMember(SqlMapClient smc,String memId);
	
	/*
	 *	MemberVo객체에 담긴 회원정보를 ㅣㅇ요하여 회원을 검색하는 메소드 
	 *  @param mv 검색할 자효가 들어있는 MemberVO 객체
	 *  @return 검색된 결과를 담은 List객체
	 */
	
	public List<MemberVO> searchMemberList(SqlMapClient smc,MemberVO mv);
	
}

MemberDaoImpl

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.management.RuntimeErrorException;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.or.ddit.member.vo.MemberVO;
import kr.or.ddit.util.sqlMapClientFactory;

public class MemberDaoImpl implements IMemberDAO{
	
	private static IMemberDAO memDAO;
	
	private MemberDaoImpl() {
		
	}
	
	
	public static IMemberDAO getInstance() {
		if(memDAO == null) {
			memDAO = new MemberDaoImpl();
		}
		return memDAO;
	}
	
	
	@Override
	public int insertMember(SqlMapClient smc,MemberVO mv) {
		
		int cnt = 0;

		try {
			cnt = smc.update("member.insertMember",mv);
			
		} catch (SQLException ex) {
			ex.printStackTrace();
			throw new RuntimeException("회원정보 입력중 예외 발생",ex);
			// 일어날지 안일어날지 모르지만 예외처리 (런타임시점에서 일어나는것) = 언체크드 에러 = 강제성 없다
		}
		
		return cnt;
	}

	
	
	
	@Override
	public int updateMember(SqlMapClient smc,MemberVO mv) {
		
		int cnt =0;
		
		try {
			cnt = smc.update("member.updateMember",mv);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("회원정보 수정중 예외 발생",e);
		} 
		return cnt;
	}

	
	
	
	@Override
	public int deleteMember(SqlMapClient smc,String memId) {
		int cnt =0;
		try {
			cnt = smc.delete("member.deleteMember",memId);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("회원정보 삭제중 예외발생",e);
		}
		return cnt;
	}

	
	
	
	@Override
	public List<MemberVO> getAllMemberList(SqlMapClient smc) {
		
		List<MemberVO> memList = new ArrayList<MemberVO>();		
		
		try {
			memList = smc.queryForList("member.getMemberAll");
		} catch (SQLException e) {
			e.printStackTrace();
			 new RuntimeException("전체 회원정보 조회중 예외발생",e);
		} 
		return memList;
	}

	
	
	
	@Override
	public boolean checkMember(SqlMapClient smc,String memId) {
		boolean chk = false; //회원 존재여부 체크
		try {
			
			int cnt=(int) smc.queryForObject("member.checkMember",memId);
			
			if(cnt>0) { //중복이 존재한다
				chk=true;
			}
			
			
		} catch (SQLException ex) {
			ex.printStackTrace();
			throw new RuntimeException("회원정보 중복체크중 예외 발생!",ex);
		}
		return chk;
	}

	@Override
	public List<MemberVO> searchMemberList(SqlMapClient smc,MemberVO mv) {
		
		List<MemberVO> memList = new ArrayList<MemberVO>();
		try {
			memList = smc.queryForList("member.searchMember",mv);
			
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("회원정보 검색중 예외 발생!",e);
		}
		return memList;
	}

}

IMemberService

import java.util.List;

import kr.or.ddit.member.vo.MemberVO;

// Service객체는 DAO에 설정된 메서드를 원하는 작업에 맞게호출하여 결과를 받아오고,
// 받아온 자료를 Controller에게 보내주는 역할을한다

// +)만약 메일을 보낼때 메일을 보내는 DAO를 쓰고 마지막에 그 기록까지 남기려면 기록을 남기는 DAO까지 Service에 써줘야.

public interface IMemberService {
	
	
	//public int insertMember();
	// 여기 매개변수로 String name, String 어쩌구 ... 주면 나중에 유지보수가 귀찮을것같아 => VO를 만들자!
	
	
	
	// MemberVO에 감겨진 자료를 DB에 insert하는 메소드
	// @param mv DB에 insert할 자료가 저장된 MemberVO객체
	// @return DB작업이 성공하며 1이상의 값이 반환되고 실패하면 0이 반환된다
	public int insertMember(MemberVO mv);
	
	
	
	/**
		하나의 MemberVO 객체를 받아서 DB에 update하는메서드
		@param mv update할 회원정보가 들어있는 MemberVO객체
		@return 작업성공:1, 작업실패:0
	  
	*/
	public int updateMember(MemberVO mv);

	
	
	/*
		회원Id를 매개변수로 받아서 그 회원정보를 삭제하는 메서드
		 @param memId 삭제할 회원ID
		 @return 작업성공:1, 작업실패:0
	*/
	public int deleteMember(String memId);
	
	
	
	/*
		DB의 mymember테이블에 있는 전체레코드를 가져와서 List에 담아 반환하는 메서드
		@return MemberVO객체를 담고있는 List객체
	*/
	public List<MemberVO> getAllMemberList();
	
	
	
	/*
		주어진 회원ID가 존재하는지 여부를 알아내는 메소드
		@param memId 검색할 회원ID
		@return 해당회원ID가 있으면 true, 없으면 false
	
	*/
	public boolean checkMember(String memId);
	/*
	 *	MemberVo객체에 담긴 회원정보를 ㅣㅇ요하여 회원을 검색하는 메소드 
	 *  @param mv 검색할 자효가 들어있는 MemberVO 객체
	 *  @return 검색된 결과를 담은 List객체
	 */
	
	public List<MemberVO> searchMemberList(MemberVO mv);
	
}

MemberServiceImpl

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

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.or.ddit.member.dao.IMemberDAO;
import kr.or.ddit.member.dao.MemberDaoImpl;
import kr.or.ddit.member.vo.MemberVO;
import kr.or.ddit.util.sqlMapClientFactory;

public class MemberServiceImpl implements IMemberService{

	private static IMemberService memService;
	private IMemberDAO memDAO;
	private SqlMapClient smc;
	
	private MemberServiceImpl() {
		memDAO = MemberDaoImpl.getInstance();
		smc = sqlMapClientFactory.getInstance();
	}
	
	public static IMemberService getInstance() {
		if(memService == null) {
			memService = new MemberServiceImpl();
		}
		
		return memService;
}

	@Override
	public int insertMember(MemberVO mv) {
		try {
			smc.startTransaction();//트랜잭션 시작
			int cnt = memDAO.insertMember(smc, mv);
			smc.commitTransaction(); // 커밋...
		} catch (SQLException e) {
			try {
				smc.endTransaction(); //롤백
			} catch (SQLException e1) {
				e1.printStackTrace();
			} 
		} 
		
		return memDAO.insertMember(smc,mv);
	}

	@Override
	public int updateMember(MemberVO mv) {
		return memDAO.updateMember(smc,mv);
	}

	@Override
	public int deleteMember(String memId) {
		return memDAO.deleteMember(smc,memId);
	}

	@Override
	public List<MemberVO> getAllMemberList() {
		return memDAO.getAllMemberList(smc);
	}

	@Override
	public boolean checkMember(String memId) {
		return memDAO.checkMember(smc,memId);
	}

	@Override
	public List<MemberVO> searchMemberList(MemberVO mv) {
		return memDAO.searchMemberList(smc,mv);
	}

}

MemberVO

public class MemberVO {
	
	private String memId;
	private String memName;
	private String memTel;
	private String memAddr;
	
	public String getMemId() {
		return memId;
	}
	public void setMemId(String memId) {
		this.memId = memId;
	}
	public String getMemName() {
		return memName;
	}
	public void setMemName(String memName) {
		this.memName = memName;
	}
	public String getMemTel() {
		return memTel;
	}
	public void setMemTel(String memTel) {
		this.memTel = memTel;
	}
	public String getMemAddr() {
		return memAddr;
	}
	public void setMemAddr(String memAddr) {
		this.memAddr = memAddr;
	}
	
	
	@Override
	public String toString() {
		return "MemberVO [memId=" + memId + ", memName=" + memName + ", memTel=" + memTel + ", memAddr=" + memAddr
				+ "]";
	}
	
	
	
}

MemberInfoMain

import java.util.List;
import java.util.Scanner;

import kr.or.ddit.member.service.IMemberService;
import kr.or.ddit.member.service.MemberServiceImpl;
import kr.or.ddit.member.vo.MemberVO;

/*
	회원정보를 관리하는 프로그램을 작성하는데 
	아래의 메뉴를 모두 구현하시오. (CRUD기능 구현하기)
	(DB의 MYMEMBER테이블을 이용하여 작업한다.)
	
	* 자료 삭제는 회원ID를 입력 받아서 삭제한다.
	
	예시메뉴)
	----------------------
		== 작업 선택 ==
		1. 자료 입력			---> insert
		2. 자료 삭제			---> delete
		3. 자료 수정			---> update
		4. 전체 자료 출력	---> select
		5. 작업 끝.
	----------------------
	 
	   
// 회원관리 프로그램 테이블 생성 스크립트 
create table mymember(
    mem_id varchar2(8) not null,  -- 회원ID
    mem_name varchar2(100) not null, -- 이름
    mem_tel varchar2(50) not null, -- 전화번호
    mem_addr varchar2(128),    -- 주소
    reg_dt DATE DEFAULT sysdate, -- 등록일
    CONSTRAINT MYMEMBER_PK PRIMARY KEY (mem_id)
);

*/
public class MemberInfoMain {
	
	private IMemberService memService;
	private Scanner scan = new Scanner(System.in); 
	
	public MemberInfoMain() {
		memService = MemberServiceImpl.getInstance();
	}
	
	/**
	 * 메뉴를 출력하는 메서드
	 */
	public void displayMenu(){
		System.out.println();
		System.out.println("----------------------");
		System.out.println("  === 작 업 선 택 ===");
		System.out.println("  1. 자료 입력");
		System.out.println("  2. 자료 삭제");
		System.out.println("  3. 자료 수정");
		System.out.println("  4. 전체 자료 출력");
		System.out.println("  5. 자료 검색");
		System.out.println("  6. 작업 끝.");
		System.out.println("----------------------");
		System.out.print("원하는 작업 선택 >> ");
	}
	
	/**
	 * 프로그램 시작메서드
	 */
	public void start(){
		int choice;
		do{
			displayMenu(); //메뉴 출력
			choice = scan.nextInt(); // 메뉴번호 입력받기
			switch(choice){
				case 1 :  // 자료 입력
					insertMember();
					break;
				case 2 :  // 자료 삭제
					deleteMember();
					break;
				case 3 :  // 자료 수정
					updateMember();
					break;
				case 4 :  // 전체 자료 출력
					displayMemberAll();
					break;
				case 5 :  // 자료검색
					searchMember();
					break;
				case 6 :  // 작업 끝
					System.out.println("작업을 마칩니다.");
					break;
				default :
					System.out.println("번호를 잘못 입력했습니다. 다시입력하세요");
			}
		}while(choice!=6);
	}
	
	
	
	//회원정보를 검색하는 메서드
	private void searchMember() {
		// 검색할 회원ID, 회원이름, 전화번호, 주소 등을 입력하면 입력한 정보만을 사용하여 검색하는기능을 구현하시오
		// 주소는 입력한 값이 포함만 되어도 검색되도록 한다
		// 입력을 하지 않을 자료는 앤터키로 다음입력으로 넘긴다.
		scan.nextLine(); //입력버퍼 비우기
		System.out.println();
		System.out.println("검색할 정보를입력하세요");
		
		System.out.print("회원 ID>> ");
		String memId=scan.nextLine().trim(); //trim은 혹시모를 공백제거
		
		System.out.print("회원 이름>> ");
		String memName = scan.nextLine().trim();
		
		System.out.print("회원 전화번호>> ");
		String memTel = scan.nextLine().trim();
		
		System.out.print("회원 주소>> ");
		String memAddr = scan.nextLine().trim();
		
		MemberVO mv = new MemberVO();
		mv.setMemId(memId);
		mv.setMemId(memId);
		mv.setMemTel(memTel);
		mv.setMemAddr(memAddr);
		
		List<MemberVO> memList = memService.searchMemberList(mv);
		
		
		
		System.out.println();
		System.out.println("---------------------------------------");
		System.out.println(" ID\t이름\t전화번호\t\t주소");
		System.out.println("---------------------------------------");
		
		
		if(memList.size()==0) {
			System.out.println("회원정보가 존재하지 않습니다");
		} else {
			
			for(MemberVO mv2 : memList) {
				System.out.println(mv2.getMemId()+"\t"+mv2.getMemName()+"\t"+mv2.getMemTel()+"\t\t"+mv2.getMemAddr());				
			}
		}
		
		
		System.out.println("---------------------------------------");
		System.out.println("검색 작업 끝");
	}

	
	
	
	// 회원정보를 삭제하기 위한 메소드
	private void deleteMember() {
		System.out.println();
		System.out.println("삭제할 회원정보를 입력하세요");
		System.out.print("회원 ID : ");
		
		String memId = scan.next();
		
		int cnt = memService.deleteMember(memId);
		if(cnt >0) {
			System.out.println(memId+"회원정보를 삭제했습니다");
		}else {
		System.out.println(memId+"회원정보를 삭제 실패");
		}
		
		
	}

	// 회원정보 수정하기 위한 메서드
	private void updateMember() {
		boolean chk = false; //등록여부 체크
		String memId ="";
		
		do {
			System.out.println();
			System.out.println("추가할 회원정보를 입력하세요");
			System.out.print("회원 ID : ");
			
			memId = scan.next();
			
			chk = checkMember(memId);
			
			if(chk==false) {
				System.out.println("회원ID가 "+memId+"인 회원 존재하지 않습니다.");
				System.out.println("다시 입력하세요");
			}
			
		} while(chk==false); //중복 없을때
		
		System.out.println("회원이름 >> ");
		String memName = scan.next();
		System.out.println("회원 전화번호 >> ");
		String memTel = scan.next();
		scan.nextLine(); // 버퍼 비우기
		System.out.println("회원주소 >> ");
		String memAddr = scan.nextLine();
		
		MemberVO mv = new MemberVO();
		mv.setMemId(memId);
		mv.setMemName(memName);
		mv.setMemTel(memTel);
		mv.setMemAddr(memAddr);
		
		int cnt = memService.updateMember(mv);
		// 이제 업데이트를 시켜줘보자!!!
			
			if(cnt>0) {
				System.out.println(memId+"회원이 정보를 수정했습니다");
			}else {
				System.out.println(memId+"회원의 정보 수정 실패");
			}

		
		
	}

	// 전체회원정보를 출력하는 메서드
	private void displayMemberAll() {
		System.out.println();
		System.out.println("---------------------------------------");
		System.out.println(" ID\t이름\t전화번호\t\t주소");
		System.out.println("---------------------------------------");
		
		List<MemberVO> memList = memService.getAllMemberList();
		
		if(memList.size()==0) {
			System.out.println("회원정보가 존재하지 않습니다");
		} else {
			
			for(MemberVO mv : memList) {
				System.out.println(mv.getMemId()+"\t"+mv.getMemName()+"\t"+mv.getMemTel()+"\t\t"+mv.getMemAddr());				
			}
		}
		
		
		
		System.out.println("---------------------------------------");
		System.out.println("출력작업 끝");
	}
	
	
	
	
	
	
	

	// 회원을 추가하는 메서드
	private void insertMember() {
		boolean chk = false; //등록여부 체크
		String memId ="";
		
		do {
			System.out.println();
			System.out.println("추가할 회원정보를 입력하세요");
			System.out.print("회원 ID : ");
			
			memId = scan.next();
			chk = checkMember(memId);
			
			if(chk==true) {
				System.out.println("회원ID가 "+memId+"인 회원은 이미 존재합니다");
				System.out.println("다시 입력하세요");
			}
			
		} while(chk==true);
		
		System.out.println("회원이름 >> ");
		String memName = scan.next();
		System.out.println("회원 전화번호 >> ");
		String memTel = scan.next();
		scan.nextLine(); // 버퍼 비우기
		System.out.println("회원주소 >> ");
		String memAddr = scan.nextLine();
		
		MemberVO mv = new MemberVO();
		mv.setMemId(memId);
		mv.setMemName(memName);
		mv.setMemTel(memTel);
		mv.setMemAddr(memAddr);
		
		int cnt = memService.insertMember(mv);
		
			if(cnt>0) {
				System.out.println(memId+"회원 추가 작업 성공");
			}else {
				System.out.println(memId+"회원 추가 작업 실패");				
			}

		
	}
	
	// 회원 아이디를 이용하여 회원이 존재하는지 알려주는 메소드
	// @param memId
	// @return true : 회원이 존재함, false : 회원이 존재하지 않음
	private boolean checkMember(String memId) {
		return memService.checkMember(memId);
	}

	
	public static void main(String[] args) {
		MemberInfoMain memObj = new MemberInfoMain();
		memObj.start();
	}
}

sqlMapClientFactory

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

/**
 * sqlMapClient 객체를 제공하는 팩토리클래스
 * @author 306-02
 *
 */
public class sqlMapClientFactory {
	
	private static SqlMapClient smc; //SqlMapClient 객체변수 선언
	
	/**
	 * sqlMapClient 객체를 제공하는 팩토리메서드
	 * @return SqlMapClient객체
	 *
	 */
	
	public static SqlMapClient getInstance() {
		if(smc == null) {
			try {
				// 1-1. xml 문서 읽어오기
				Charset charset = Charset.forName("UTF-8"); //설정파일 인코딩 정보 설정
				Resources.setCharset(charset);
				Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
				
				// 위에 static으로 생성한 smc를 그대로 사용!
				//SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);
				smc = SqlMapClientBuilder.buildSqlMapClient(rd);
				rd.close(); // Reader객체 닫기
			} catch(IOException ex) {
				ex.printStackTrace();
			}
			
		}
		
		return smc;
	}

}

member.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
			PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
			"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="member">
	
<!--  
	이 영역에 sql문에 맞는 태그를 사용하여 SQL문을 기술한다.
	
	사용 할 수 있는 기본적인 태그들
	 <select> ~~~ </select>
	 <insert> ~~~ </insert>
	 <update> ~~~ </update>
	 <delete> ~~~ </delete>
	 
	 위 태그에서 사용되는 속성들
	 1) id속성 : 해당태그를 호출할 때 <sqlMap>태그의 namespace와 연결하여 사용하는 이름
	 2) parameterClass 속성 : sql문에 사용할 데이터가 들어있는 객체타입을 지정한다
	 					(보통 VO클래스, 자바의 자료형이름 등이 사용된다)
	 					(typeAlias로 지정한 alias명을 사용할 수 잇다)
	 3) resultClass 속성 : select문을 실행한 결과를 담을 객체를 지정한다.
	 					(보통 VO클래스나 자바의 자료형이름을 사용한다.)
	 					(typeAlias로 지정한 alias명을 사용할 수 잇다)
	 4) resultMap 속성 : 결과 레코드 컬럼명과 VO객체의 property명이 다를 경우에 적절한 매핑을 위해 사용한다
	 
 -->

	<insert id="insertMember" parameterClass="kr.or.ddit.member.vo.MemberVO">
	
		insert into mymember
		(mem_id,mem_name, mem_tel, mem_addr)
		values(#memId#,#memName#,#memTel#,#memAddr#)
	
	</insert>
	
	<update id="updateMember" parameterClass="memVO">
		update mymember
				set mem_name = #memName#,
					mem_tel = #memTel#,
					mem_addr = #memAddr#
				where mem_id = #memId#
	</update>
	
	
	<delete id="deleteMember" parameterClass="String">
		delete from mymember
		where mem_id = #memId#
	</delete>
	
	
<!-- 	<select id="getMemberAll" resultClass="memVO">
	 VO의 메소드에 적절히  매핑하기위해 sql문이 만드는 가상테이블의 컬럼명을 변경
		 select mem_id as memId,
				mem_name as memName, 
				mem_tel as memTel, 
				mem_addr as memAddr 
		   from mymember
		
	</select> -->
	
	
	<resultMap class="memVO" id="memMap">
		<result property="memId" column="mem_id"/>
		<result property="memName" column="mem_name"/>
		<result property="memTel" column="mem_tel"/>
		<result property="memAddr" column="mem_addr"/>
	</resultMap>
	
	
	<select id="getMemberAll" resultMap="memMap">
	<!--  VO의 메소드에 적절히  매핑하기위해 sql문이 만드는 가상테이블의 컬럼명을 변경-->
		 select *
		   from mymember
		
	</select>
	
	
	<select id="getMember" parameterClass="String" resultMap="memMap">
		select *
		from mymember
		where mem_id = #memId#	
	</select>
	
	
	<select id="checkMember" parameterClass="String" resultClass="int">
		select count(*) as cnt 
		from mymember
		where mem_id = #memId#
	</select>
	
	
	<select id="searchMember" parameterClass="memVO" resultMap ="memMap">
		select * from mymember where 1=1
		
		<isNotEmpty property="memId">
			and mem_id = #memId#
		</isNotEmpty>
		<isNotEmpty property="memName">
			and mem_name = #memName#
		</isNotEmpty>
		<isNotEmpty property="memTel">
			and mem_tel = #memTel#
		</isNotEmpty>
		<isNotEmpty property="memAddr">
			and mem_addr like '%' || #memAddr# || '%'
		</isNotEmpty>
		
	</select>
	
</sqlMap>

sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
	<!--
	DB와 연결하는 정보를 properties파일에 설정해 놓고 이 properties파일의
	내용을 읽어와 설정한다.
	 -->
	<properties resource="db.properties" />

	<!-- ibatis를 처리하기 위한 환경설정 부분 -->
	<settings cacheModelsEnabled="true" enhancementEnabled="true"
		lazyLoadingEnabled="true" maxRequests="32" maxSessions="10"
		maxTransactions="5" useStatementNamespaces="true" />

	<!--
	VO클래스등의 이름이 패키지명까지 기술하면 길어지는데 이것을 간단히
	표시하기 위해서 alias를 지정할 수 있다.
	형식) <typeAlias alias="alias명" type="클래스의 풀네임"/>
	 -->
	<typeAlias alias="memVO" type="kr.or.ddit.member.vo.MemberVO"/>

	<!--
	DB와의 연결을 처리하는 부분
	SqlMapConfig.properties에 설정해 놓은 정보를 이용하여 구성한다.
	1. SIMPLE => SimpleDataSourceFactory
		SimpleDataSource는 데이터소스를 제공하는 컨테이너가 없는 경우 connection을 제공하기 위해 기본적으로 pooling 데이터소스 구현을 제공한다.
		이것은 iBATIS SimpleDataSource connection pooling을 기반으로 한다.

	2. DBCP => DbcpDataSourceFactory
	DbcpDataSourceFactoryDataSource API를 통해 connection pooling 서비스를 제공하기 위해 DBCP를 사용한다.DataSource는 어플리케이션/웹 컨테이너가 DataSource 구현물을 제공하지 못하거나 standalone 어플리케이션을 구동할 때 이상적이다.

    3. JNDI => JndiDataSourceFactory
 	JndiDataSourceFactory 는 어플리케이션 컨테이너내 JNDI 컨텍스트로부터 DataSource 구현물을 가져와야 한다.
 	이것은 어플리케이션 서버를 사용중이고 컨테이너 관리 connection pool 과 DataSource 가 제공될 때 사용한다.
 	JDBC DataSource 구현물에 접근하기 위한 표준적인 방법은 JNDI 컨텍스트를 통하여 접근하는 것이다.

	 -->
	<transactionManager type="JDBC">
		<dataSource type="SIMPLE">
		<!--
			각종 설정을 직접 기술해서 처리할 수도 있다.
			<property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver" />
		 -->
			<property name="JDBC.Driver" value="${driver}" />
			<property name="JDBC.ConnectionURL" value="${url}" />
			<property name="JDBC.Username" value="${username}" />
			<property name="JDBC.Password" value="${password}" />
			<!-- 커넥션 개수를 1개로 설정함. -->
			<property name="Pool.MaximumActiveConnections" value="1"/>
			<property name="Pool.MaximumIdleConnections" value="1"/>
		</dataSource>
	</transactionManager>

	<!--
	실제 처리할 SQL문은 xml문서로 따로 만든 후
	그 xml문서와 아래와 같이 연결하여 사용한다.
	형식) <sqlMap resource="경로명/파일명.xml"/>
	-->
	<sqlMap resource="sqlmap/member.xml"/>
	
</sqlMapConfig>

transaction단위로 처리하기

  • 배웠는데 이해도 안되고 안돌아가서 일단 보류

0개의 댓글