ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • myBatis(2),Lombok-22.06.28
    웹프로그래밍 2022. 6. 28. 23:41
    728x90

    insert , update, delete myBatis적용해보자 

     

    <insert>

    클라이언트가 PK입력 안할때 사용 selectKey --차후 상품관리할떄 필요 

    아이디 직접 받으니까 우리가 만들어줄 필요없어 

     

    SqlSession 이 내부에서 sqlException을 런타임 익셉션으로 바꾸고 있따

    insert할때

    SELECT ',' ||'#{'||SNAKETOCAMEL(COLUMN_NAME) ||'}'
    FROM COLS
    WHERE TABLE_NAME ='MEMBER';

    ,는 항상 앞에 있는것이 수정하기 쉽다.

      => 컬럼에 대한 상수 정의해놓음 

      jdbcType=VARCHAR null데이터 데이터베이스에  어떻게 집어넣줄거냐 

    <Member.xml , inert작업>

    <mapper namespace="kr.or.ddit.member.dao.MemberDAO">	
        <insert id="insertMember" parameterType="MemberVO">
    		INSERT INTO MEMBER ( 
    		 MEM_ID
    		,MEM_PASS
    		,MEM_NAME
    		,MEM_REGNO1
    		,MEM_REGNO2
    		,MEM_BIR
    		,MEM_ZIP
    		,MEM_ADD1
    		,MEM_ADD2
    		,MEM_HOMETEL
    		,MEM_COMTEL
    		,MEM_HP
    		,MEM_MAIL
    		,MEM_JOB
    		,MEM_LIKE
    		,MEM_MEMORIAL
    		,MEM_MEMORIALDAY
    		,MEM_MILEAGE		  
    		) VALUES (                                                                          
    			#{memId,jdbcType=VARCHAR}
    			,#{memPass,jdbcType=VARCHAR}
    			,#{memName,jdbcType=VARCHAR}
    			,#{memRegno1,jdbcType=VARCHAR}
    			,#{memRegno2,jdbcType=VARCHAR}
    			,TO_DATE(#{memBir,jdbcType=DATE},'YYYY-MM_DD')
    			,#{memZip,jdbcType=VARCHAR}
    			,#{memAdd1,jdbcType=VARCHAR}
    			,#{memAdd2,jdbcType=VARCHAR}
    			,#{memHometel,jdbcType=VARCHAR}
    			,#{memComtel,jdbcType=VARCHAR}
    			,#{memHp,jdbcType=VARCHAR}
    			,#{memMail,jdbcType=VARCHAR}
    			,#{memJob,jdbcType=VARCHAR}
    			,#{memLike,jdbcType=VARCHAR}
    			,#{memMemorial,jdbcType=VARCHAR}
    			,TO_DATE(#{memMemorialday,jdbcType=DATE},'YYYY_MM_DD')
    			,1000
    			               
    		)	
    		                                          	
    	</insert>
       </mapper>

    insert됐다는데 db에 없어 트랜잭션이 자동으로 롤백을 해버렸기에 안나오는것이다.

    rollback (복원)이나 commit했어야 함 

    영구저장하려면 커밋을 해야함 

    <MemberDAOImpl>

    원래코드

    @Override
    	public int insertMember(MemberVO member) {
    		                                                 
    		try (
    				SqlSession sqlSession =sqlSessionFactory.openSession();
    			) {
    			
    			//sqlSession.insert("kr.or.ddit.member.dao.MemberDAOImpl.insertMember", member);
    			MemberDAO mapper = sqlSession.getMapper(MemberDAO.class);
    			return mapper.insertMember(member);
    		} 
    	}

    커밋 적용

    @Override
    	public int insertMember(MemberVO member) {
    		                                                 
    		try (
    				SqlSession sqlSession =sqlSessionFactory.openSession();
    			) {
    			
    			//sqlSession.insert("kr.or.ddit.member.dao.MemberDAOImpl.insertMember", member);
    			MemberDAO mapper = sqlSession.getMapper(MemberDAO.class);
    			int rowcnt = mapper.insertMember(member);
    			sqlSession.commit();
    			return rowcnt;
    		} 
    	}

    test

    => 들어간것을 알 수 있음 

     

    트랜잭션 관리 

    트랜잭션 :작업의 단위 

    insert, update, delete할때 필요함 

    • Atomicity (원자성) : 더이상 세부단위로 쪼갤 수 없음 
    • Consistency (일관성): 일관성은 데이터베이스의 상태가 일관되어야 한다는 성질이다
    • Isolation (격리성, 고립성) :  트랜잭션과 다른 트랜잭션은 완전히 분리 , ex) 돈넣고 돈뽑는 행위동시에 일어날때
    • Durability (지속성) : 지속성은 하나의 트랜잭션이 성공적으로 수행되었다면, 해당 트랜잭션에 대한 로그가 남아야하는 성질을 말한다.

     

    	@Override
    	public int insertMember(MemberVO member) {
    		                                                 
    		try (
    				SqlSession sqlSession =sqlSessionFactory.openSession();
    			) {
    			
    			//sqlSession.insert("kr.or.ddit.member.dao.MemberDAOImpl.insertMember", member);
    			MemberDAO mapper = sqlSession.getMapper(MemberDAO.class);
    			int rowcnt = mapper.insertMember(member);
    			//sqlSession.commit();  여기 주석처리하면 롤백 됨
    			return rowcnt;
    		} 
    	}

    => 롤백이 됨 

    돈넣었는데 돈 넣기 전으로된것처럼 그래서 꼭 sqlSession.commit(); 잔액이 변경됐다면 그 변경된것이 유지 되야함 

     

    게시글 하나를 작성

    --트랜잭션 시작 (성공 or 실패)

    게시글을 작성하여  board테이블이 삽입

    해당게시글에 3개의 첨부파일이 종속됨

    첨부파일 하나하나를 attach테이블에 삽입 

    --트랜잭션 종료

    DAO두개인데 누가 트랜잭션 대상?  대상은 로직하나여야한다.(트랜잭션) 

    그래서 dao구조가 완전 달라지기도한다. dao가 아니라 service될 수도있음 


    DB 코드조각 정리하기 -- 다시하기

    update,delete

    -업데이트 할 수 없는건 안됨 ... 얘를들면 주민번호 , PK ,비번 

    -delte할때 <delete> 사용가능하고 <update>도가능 

    <MemberDAOImpl>

    @Override
    	public int updateMember(MemberVO member) {
    		try(
    			SqlSession sqlSession = sqlSessionFactory.openSession();	
    		){
    			MemberDAO mapper = sqlSession.getMapper(MemberDAO.class);
    			int rowcnt = mapper.updateMember(member);
    			sqlSession.commit();
    			return rowcnt;
    		}
    	}
    
    
    	@Override
    	public int deleteMember(String memId) {
    		try(
    			SqlSession sqlSession = sqlSessionFactory.openSession();	
    		){
    			MemberDAO mapper = sqlSession.getMapper(MemberDAO.class);
    			int rowcnt = mapper.deleteMember(memId);
    			sqlSession.commit();
    			return rowcnt;
    		}
    	}

    <Member.xml>

    <mapper namespace="kr.or.ddit.member.dao.MemberDAO">
    <update id="updateMember" parameterType="MemberVO">
    		UPDATE MEMBER
    		SET
    			MEM_NAME = #{memName,jdbcType=VARCHAR}
    			, MEM_ZIP = #{memZip,jdbcType=CHAR}
    			, MEM_ADD1 = #{memAdd1,jdbcType=VARCHAR}
    			, MEM_ADD2 = #{memAdd2,jdbcType=VARCHAR}
    			, MEM_HOMETEL = #{memHometel,jdbcType=VARCHAR}
    			, MEM_COMTEL = #{memComtel,jdbcType=VARCHAR}
    			, MEM_HP = #{memHp,jdbcType=VARCHAR}
    			, MEM_MAIL = #{memMail,jdbcType=VARCHAR}
    			, MEM_JOB = #{memJob,jdbcType=VARCHAR}
    			, MEM_LIKE = #{memLike,jdbcType=VARCHAR}
    			, MEM_MEMORIAL = #{memMemorial,jdbcType=VARCHAR}
    			, MEM_MEMORIALDAY = #{memMemorialday,jdbcType=DATE}
    		WHERE MEM_ID = #{memId,jdbcType=VARCHAR}
    	</update>
    	
    	<update id="deleteMember" parameterType="string">
    		UPDATE MEMBER
    		SET MEM_DELETE = 'Y'
    		WHERE MEM_ID = #{memId}
    	</update>
        </mapper>

     

    <MemberDAOTest.java>

    package kr.or.ddit.member.dao;
    
    import static org.junit.Assert.*;
    
    import java.sql.SQLException;
    import java.util.List;
    
    import org.junit.Before;
    import org.junit.Test;
    
    import kr.or.ddit.vo.MemberVO;
    
    public class MemberDAOTest {
    	MemberDAO dao = new MemberDAOImpl();
    	MemberVO member;
    	
    	@Before
    	public void setUp() {
    		member = new MemberVO();
    		member.setMemId("a011");
    		member.setMemPass("java");
    		member.setMemName("신규");
    		member.setMemBir("1999-01-01");
    		member.setMemZip("000-000");
    		member.setMemAdd1("대전");
    		member.setMemAdd2("오류");
    		member.setMemHp("000-000-0000");
    		member.setMemMail("aa@gmail.net");
    	} // 매 테스트 케이스가 실행되기전에 먼저 실행 insert, 
    	//update보다 먼저 실행되어야함 만약에 실행문 4개라면 4개가 독립적으로 사용할 수 있는데이터 만들어줌
    			
    
    	@Test
    	public void testSelectMemberForAuth() {
    		MemberVO inputData = new MemberVO();
    		inputData.setMemId("a001");
    		MemberVO member = dao.selectMemberForAuth(inputData);
    		System.out.println(member);
    		assertNotNull(member);
    	}
    
    	@Test(expected=RuntimeException.class)
    	public void testInsertMemberThrow() {
    		MemberVO member = new MemberVO();
    		dao.insertMember(member);
    	}
    	
    	@Test
    	public void testInsertMember() {
    			
    		int rowcnt = dao.insertMember(member);
    		assertEquals(1, rowcnt);
    		
    	}
    
    	@Test
    	public void testSelectMemberList() {
    		List<MemberVO> memberList = dao.selectMemberList();
    		assertNotNull(memberList);
    		assertNotEquals(0, memberList.size());
    		System.out.println(memberList);
    	}
    	
    	@Test
    	public void testSelectMember() {
    		assertNotNull(dao.selectMember("a001"));
    		
    	}
    	
    	@Test
    	public void updateMember() {
    		
    		member.setMemId("a002");
    		int rowcnt = dao.updateMember(member);
    		assertEquals(1, rowcnt);
    	}
    	
    	@Test
    	public void deleteMember() {
    		int rowcnt =dao.deleteMember("a002");
    		assertEquals(1, rowcnt);
    	}
    
    }

    a001 delete하려고 하니 에러 -> 제약조건 위배 , 외래키때문 즉 a001사용하고 있는 다른 테이블 존재 

    제약조건 확인

    R- 릴레이션 , a001삭제할 수 없어 a001삭제하려면 자식을 삭제해야함 

    <delete id="deleteMember" parameterType="string">
    		DELETE FROM MEMBER
    		WHERE MEM_ID=#{memID}
    	</delete>

    가 아닌

    <update id="deleteMember" parameterType="string">
    		UPDATE MEMBER
    		SET MEM_DELETE='Y'
    		WHERE MEM_ID=#{memID}
    	</update>

    탈퇴 회원 제외하고 조회 

    <select id="selectMemberList" resultType="MemberVO">
    		SELECT MEM_ID, MEM_NAME, MEM_HP      
    			, MEM_ADD1, MEM_MAIL, MEM_MILEAGE 
    		FROM MEMBER	
    		WHERE MEM_DELETE IS NULL                      
    	</select>

    탈퇴한사람 로그인 못하게

    <select id="selectMemberForAuth" parameterType="MemberVO" resultType="MemberVO">
    		 SELECT MEM_ID, MEM_PASS, MEM_NAME, MEM_HP, MEM_ADD1  
    		 FROM MEMBER                                          
    		 WHERE MEM_ID = #{memId} AND  MEM_DELETE IS NULL         
    	</select>

    그래서 총 수정한 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="kr.or.ddit.member.dao.MemberDAO">
    	<select id="selectMemberForAuth" parameterType="MemberVO" resultType="MemberVO">
    		 SELECT MEM_ID, MEM_PASS, MEM_NAME, MEM_HP, MEM_ADD1  
    		 FROM MEMBER                                          
    		 WHERE MEM_ID = #{memId}  AND MEM_DELETE IS NULL	         
    	</select>
    	
    	<select id="selectMemberList" resultType="MemberVO">
    		SELECT MEM_ID, MEM_NAME, MEM_HP      
    			, MEM_ADD1, MEM_MAIL, MEM_MILEAGE 
    		FROM MEMBER
    		WHERE MEM_DELETE IS NULL	                      
    	</select>
    	
    	<select id="selectMember" parameterType="string" resultType="MemberVO">
    		SELECT MEM_ID,	    MEM_PASS,	    MEM_NAME,                                 
    		    MEM_REGNO1,	    MEM_REGNO2,	    TO_CHAR(MEM_BIR, 'YYYY-MM-DD') MEM_BIR,   
    		    MEM_ZIP,	    MEM_ADD1,	    MEM_ADD2,                                 
    		    MEM_HOMETEL,	    MEM_COMTEL,	    MEM_HP,                               
    		    MEM_MAIL,	    MEM_JOB,	    MEM_LIKE,                                 
    		    MEM_MEMORIAL,	TO_CHAR(MEM_MEMORIALDAY, 'YYYY-MM-DD') MEM_MEMORIALDAY,   
    		    MEM_MILEAGE,	 MEM_DELETE                                               
    		    FROM	MEMBER                                                            
    	    WHERE MEM_ID = #{memId}                                                              
    	</select>
    	
    	<insert id="insertMember" parameterType="MemberVO">
    		INSERT INTO MEMBER (                                                                 
    			MEM_ID
    			,MEM_PASS
    			,MEM_NAME
    			,MEM_REGNO1
    			,MEM_REGNO2
    			,MEM_BIR
    			,MEM_ZIP
    			,MEM_ADD1
    			,MEM_ADD2
    			,MEM_HOMETEL
    			,MEM_COMTEL
    			,MEM_HP
    			,MEM_MAIL
    			,MEM_JOB
    			,MEM_LIKE
    			,MEM_MEMORIAL
    			,MEM_MEMORIALDAY
    			,MEM_MILEAGE
    		) VALUES (                                                                       
    			 #{memId,jdbcType=VARCHAR}
    			, #{memPass,jdbcType=VARCHAR}
    			, #{memName,jdbcType=VARCHAR}
    			, #{memRegno1,jdbcType=VARCHAR}
    			, #{memRegno2,jdbcType=VARCHAR}
    			, TO_DATE(#{memBir,jdbcType=DATE}, 'YYYY-MM-DD')
    			, #{memZip,jdbcType=VARCHAR}
    			, #{memAdd1,jdbcType=VARCHAR}
    			, #{memAdd2,jdbcType=VARCHAR}
    			, #{memHometel,jdbcType=VARCHAR}
    			, #{memComtel,jdbcType=VARCHAR}
    			, #{memHp,jdbcType=VARCHAR}
    			, #{memMail,jdbcType=VARCHAR}
    			, #{memJob,jdbcType=VARCHAR}
    			, #{memLike,jdbcType=VARCHAR}
    			, #{memMemorial,jdbcType=VARCHAR}
    			, TO_DATE(#{memMemorialday,jdbcType=DATE}, 'YYYY-MM-DD')
    			, 1000
    		)		                                                                             
    	</insert>
    	
    	<update id="updateMember" parameterType="MemberVO">
    		UPDATE MEMBER
    		SET
    			MEM_NAME = #{memName,jdbcType=VARCHAR}
    			, MEM_ZIP = #{memZip,jdbcType=CHAR}
    			, MEM_ADD1 = #{memAdd1,jdbcType=VARCHAR}
    			, MEM_ADD2 = #{memAdd2,jdbcType=VARCHAR}
    			, MEM_HOMETEL = #{memHometel,jdbcType=VARCHAR}
    			, MEM_COMTEL = #{memComtel,jdbcType=VARCHAR}
    			, MEM_HP = #{memHp,jdbcType=VARCHAR}
    			, MEM_MAIL = #{memMail,jdbcType=VARCHAR}
    			, MEM_JOB = #{memJob,jdbcType=VARCHAR}
    			, MEM_LIKE = #{memLike,jdbcType=VARCHAR}
    			, MEM_MEMORIAL = #{memMemorial,jdbcType=VARCHAR}
    			, MEM_MEMORIALDAY = #{memMemorialday,jdbcType=DATE}
    		WHERE MEM_ID = #{memId,jdbcType=VARCHAR}
    	</update>
    	
    	<update id="deleteMember" parameterType="string">
    		UPDATE MEMBER
    		SET MEM_DELETE = 'Y'
    		WHERE MEM_ID = #{memId}
    	</update>
    </mapper>

    <마이페이지 만들기 > 수정,탈퇴하기 

    이제 서비스 단을 건들여보자 비지니스 로직!!!

    <MemberService>

    package kr.or.ddit.member.service;
    
    import java.util.List;
    
    import kr.or.ddit.enumpkg.ServiceResult;
    import kr.or.ddit.exception.PKNotFoundException;
    import kr.or.ddit.vo.MemberVO;
    
     /**
     * 회원관리(CRUD)를 위한 Business Logic Layer
     *
     */
    public interface MemberService {
    	/**
    	 * 회원가입 로직
    	 * @param member 가입할 회원의 정보를 가진VO
    	 * @return PKDUPLICATED , OK, FAIL
    	 */
    	public ServiceResult createMember(MemberVO member);
    	
    	public List<MemberVO> retrieveMemberList();
    	/**
    	 * 회원 상세 조회
    	 * @param memId 조회할 회원 아이디
    	 * @return 존재하지 않는 경우 , {@link PKNotFoundException}발생
    	 */
    	public MemberVO retrieveMember(String memId);
    	/**
    	 * 회원정보 수정
    	 * @param member
    	 * @return {@link PKNotFoundException},INVALIDPASSWORD, OK, FAIL
    	 */
    	public ServiceResult modifyMember(MemberVO member);
    	/**
    	 * 회원 탈퇴
    	 * @param member 탈퇴할 회원의 아이디와 비번
    	 * @return {@link PKNotFoundException},INVALIDPASSWORD, OK, FAIL
    	 */
        public ServiceResult removeMember(MemberVO member);
    }

    <MemberServiceImpl> 처음에 작성한 ...

    	@Override
    	public ServiceResult modifyMember(MemberVO member) {
    		ServiceResult result = null;
    //      존재 여부 확인		
    		MemberVO saved =retrieveMember(member.getMemId());
    		String inputPass = member.getMemPass();
    		String savedPass= member.getMemId();
    //      비밀번호 인증
    		if(savedPass.equals(inputPass)) {
    //수정
    		int rowcnt =memberDao.updateMember(member);
    		result=rowcnt>0?ServiceResult.OK:ServiceResult.FAIL;
    		}else {
    			result =ServiceResult.INVALIDPASSWORD;
    		}
    		return result;
    	}
    	
    	@Override
    	public ServiceResult removeMember(MemberVO member) {
    		ServiceResult result = null;
    		if(memberDao.selectMemberForAuth(member)!=null) {
    			int rowcnt =memberDao.deleteMember(member.getMemId());
    		if(rowcnt>0) {
    				result =ServiceResult.OK;
    			}else {
    				result=ServiceResult.FAIL;
    			}			
    		}else {
    			result =ServiceResult.PKDUPLICATED;
    		}
    
    		return result;
    	}

    수정 한 코드 

    비밀번호 암호화 한다면 authenticate에서 수정하면되는것이다. 

    @Override
    	public ServiceResult modifyMember(MemberVO member) {
    		MemberVO inputData = new MemberVO();
    		inputData.setMemId(member.getMemId());
    		inputData.setMemPass(member.getMemPass());
    		ServiceResult result = authService.authenticate(inputData);
    		switch (result) {
    		case NOTEXIST:
    			throw new PKNotFoundException(String.format("%s 에 해당하는 회원이 없음.", member.getMemId()));
    		case INVALIDPASSWORD:
    			break;
    		default:
    			int rowcnt = memberDao.updateMember(member);
    			result = rowcnt > 0 ? ServiceResult.OK : ServiceResult.FAIL;
    			break;
    		}
    		return result;
    	}
    
    	@Override
    	public ServiceResult removeMember(MemberVO member) {
    		ServiceResult result = authService.authenticate(member);
    		switch (result) {
    		case NOTEXIST:
    			throw new PKNotFoundException(String.format("%s 에 해당하는 회원이 없음.", member.getMemId()));
    		case INVALIDPASSWORD:
    			break;
    		default:
    			int rowcnt = memberDao.deleteMember(member.getMemId());
    			result = rowcnt > 0 ? ServiceResult.OK : ServiceResult.FAIL;
    			break;
    		}
    		return result;
    	}

    호출자에게 하나이상의 데이터 전달하고싶어 , call refernce 구조 사용  

    BeanUtils.copyProperties(inputData, member);

    member데이터 inputData 로 보냄 멤버는 반환되지 않지만 call by refernce 호출자에게 전달이 됨 

    이미 상태가 반경된 inputData에 들어와서 member데이터를 가지고 있음 

     

    <MemberUpdate.java>

    package kr.or.ddit.member.web;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.beanutils.BeanUtils;
    import org.apache.commons.lang3.StringUtils;
    
    import kr.or.ddit.enumpkg.ServiceResult;
    import kr.or.ddit.member.service.MemberService;
    import kr.or.ddit.member.service.MemberServiceImpl;
    import kr.or.ddit.mvc.DelegatingViewResolver;
    import kr.or.ddit.vo.MemberVO;
    
    @WebServlet("/member/memberUpdate.do")
    public class MemberUpdateServlet extends HttpServlet {
    	MemberService service = new MemberServiceImpl();
    	
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// 초기값을 가지고있는 수정 양식제공. member/memberForm 재활용
    //		현재 사용자의 개인 정보를 데이터베이스로 부터 조회.
    		MemberVO authMember = (MemberVO) req.getSession().getAttribute("authMember");
    		MemberVO member = service.retrieveMember(authMember.getMemId());
    		req.setAttribute("member", member);
    //		해당 정보를 초기값으로 수정UI 제공하기 위해 view layer로 이동
    		String  viewName = "/member/memberForm.tiles";
    		new DelegatingViewResolver().viewResolve(viewName, req, resp);
    	}
    	
    	@Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //		요청 파리미터에 포함된 특수문자에 대한 디코딩 방식 설정.
    		req.setCharacterEncoding("UTF-8");
    //		전달되는 여러개의 파라미터를 Domain layer 를 이용하여 바인딩.
    		Map<String, String[]> parameterMap = req.getParameterMap();
    		MemberVO member = new MemberVO();
    //		해당 VO 는 명령 처리가 완료되기 전까지 공유해야함.
    		req.setAttribute("member", member);
    		try {
    			BeanUtils.populate(member, parameterMap);
    		} catch (IllegalAccessException | InvocationTargetException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    //		요청 데이터 검증
    		Map<String, String> errors = new LinkedHashMap<>();
    		req.setAttribute("errors", errors);
    		boolean valid = validate(member, errors);
    		String viewName = null;
    		if(valid) {
    //		검증을 통과하면 로직을 사용하여 수정.
    			ServiceResult result = service.modifyMember(member);
    			switch (result) {
    			case INVALIDPASSWORD:
    				req.setAttribute("message", "비밀번호 오류");
    				viewName = "/member/memberForm.tiles";
    				break;
    			case FAIL:
    				req.setAttribute("message", "서버 오류");
    				viewName = "/member/memberForm.tiles";
    				break;
    			default:
    				viewName = "redirect:/myPage.do";
    				break;
    			}
    		}else {
    //		통과하지 못하면, 기존 입력 데이터와 검증 결과 데이터를 가지고 view layer 로 이동.
    			viewName = "/member/memberForm.tiles";
    		}
    		
    		new DelegatingViewResolver().viewResolve(viewName, req, resp);
    	}
    
    	private boolean validate(MemberVO member, Map<String, String> errors) {
    		boolean valid = true;
    		if (StringUtils.isBlank(member.getMemId())) {
    			errors.put("memId", "회원아이디 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemPass())) {
    			errors.put("memPass", "비밀번호 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemName())) {
    			errors.put("memName", "회원명 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemBir())) {
    			errors.put("memBir", "생일 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemZip())) {
    			errors.put("memZip", "우편번호 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemAdd1())) {
    			errors.put("memAdd1", "주소1 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemAdd2())) {
    			errors.put("memAdd2", "주소2 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemHp())) {
    			errors.put("memHp", "휴대폰 누락");
    			valid = false;
    		}
    		if (StringUtils.isBlank(member.getMemMail())) {
    			errors.put("memMail", "이메일 누락");
    			valid = false;
    		}
    		return valid;
    	}
    }

    <MypageServlet.java>

    package kr.or.ddit.member.web;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.beanutils.BeanUtils;
    
    import kr.or.ddit.member.service.MemberService;
    import kr.or.ddit.member.service.MemberServiceImpl;
    import kr.or.ddit.mvc.DelegatingViewResolver;
    import kr.or.ddit.vo.MemberVO;
    
    @WebServlet("/myPage.do")
    public class MypageServlet extends HttpServlet{
    	
    	MemberService service = new MemberServiceImpl();
    	
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		MemberVO authMember = (MemberVO) req.getSession().getAttribute("authMember");
    		String memId = authMember.getMemId();
    		MemberVO member = service.retrieveMember(memId);
    		req.setAttribute("member", member);
    		String viewName = "/member/myPage.tiles";
    		new DelegatingViewResolver().viewResolve(viewName, req, resp);
    		//지금 현재 상황: 검증 안하고 있구 , 로그인 안했을때 마이페이지 에러 ->  추후필터 적용
    	}
    	
    }

    <myPage.jsp>

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <table class="table table-bordered">
    	<tr>
    		<th>회원아이디</th>
    		<td>${member.memId }</td>
    	</tr>
    	<tr>
    		<th>비밀번호</th>
    		<td>${member.memPass }</td>
    	</tr>
    	<tr>
    		<th>회원명</th>
    		<td>${member.memName }</td>
    	</tr>
    	<tr>
    		<th>주민번호1</th>
    		<td>${member.memRegno1 }</td>
    	</tr>
    	<tr>
    		<th>주민번호2</th>
    		<td>${member.memRegno2 }</td>
    	</tr>
    	<tr>
    		<th>생일</th>
    		<td>${member.memBir }</td>
    	</tr>
    	<tr>
    		<th>우편번호</th>
    		<td>${member.memZip }</td>
    	</tr>
    	<tr>
    		<th>주소1</th>
    		<td>${member.memAdd1 }</td>
    	</tr>
    	<tr>
    		<th>주소2</th>
    		<td>${member.memAdd2 }</td>
    	</tr>
    	<tr>
    		<th>집전화번호</th>
    		<td>${member.memHometel }</td>
    	</tr>
    	<tr>
    		<th>회사번호</th>
    		<td>${member.memComtel }</td>
    	</tr>
    	<tr>
    		<th>휴대폰</th>
    		<td>${member.memHp }</td>
    	</tr>
    	<tr>
    		<th>이메일</th>
    		<td>${member.memMail }</td>
    	</tr>
    	<tr>
    		<th>직업</th>
    		<td>${member.memJob }</td>
    	</tr>
    	<tr>
    		<th>취미</th>
    		<td>${member.memLike }</td>
    	</tr>
    	<tr>
    		<th>기념일</th>
    		<td>${member.memMemorial }</td>
    	</tr>
    	<tr>
    		<th>기념일자</th>
    		<td>${member.memMemorialday }</td>
    	</tr>
    	<tr>
    		<th>마일리지</th>
    		<td>${member.memMileage }</td>
    	</tr>
    	<tr>
    		<th>탈퇴여부</th>
    		<td>${member.memDelete }</td>
    	</tr>
    	<tr>
    		<td colspan="2">
    			<input type="button" class="btn btn-primary linkBtn" value="수정" />
    			<input type="button" class="btn btn-danger" value="탈퇴" />
    		</td>
    	</tr>
    </table>
    
    <script>
    	$(".linkBtn").on("click", function(event){
    		location.href="${cPath}/member/memberUpdate.do";
    	});
    </script>

    <memberFrom.jsp 수정한것>

    <%@page import="org.apache.commons.lang3.StringUtils"%>
    <%@page import="java.util.Objects"%>
    <%@page import="java.util.LinkedHashMap"%>
    <%@page import="kr.or.ddit.vo.MemberVO"%>
    <%@page import="java.util.Map"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    	
    	<%
    		String message =(String)request.getAttribute("message");
    		if(StringUtils.isNotBlank(message)){
    			%>
    			<script>
    				alert("<%=message%>");
    			</script>
    			<% 
    		}
    	%>
    
    <h4>회원 가입 양식</h4>
    <%-- <%	
    	MemberVO member =(MemberVO)request.getAttribute("member");
    	if(member==null)
    		member = new MemberVO(); //강제로 빈 member만들어주기
    	Map<String,String> errors =(Map)request.getAttribute("errors");
    		if(errors==null)
    			errors = new LinkedHashMap<>();
    %> --%>
    <jsp:useBean id="member" class="kr.or.ddit.vo.MemberVO" scope="request"/>
    <jsp:useBean id="errors" class="java.util.LinkedHashMap" scope="request"/>
    <form method="post"enctype="application/x-www-form-urlencoded">
    	<table>
    		<tr>
    			<th>회원아이디</th>
    			<td>
    			<input type="text" name="memId"  class="form-control" value='<%=Objects.toString(member.getMemId(),"") %>'/>
    			<%--없으면 null나옴 <span class="error"><%=errors.get("memId")%></span> --%>
    				<span class="error">${errors['memId']}</span>
    			</td>
    		</tr>
    		<tr>
    		<th>비밀번호</th>
    		<td>
    			<input type="text" name="memPass"  value="${member.memPass }" />
    			<span class="error">${errors["memPass"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>회원명</th>
    		<td>
    			<input type="text" name="memName"  value="${member.memName }" />
    			<span class="error">${errors["memName"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>주민번호1</th>
    		<td>
    			<input type="text" name="memRegno1" value="${member.memRegno1 }" />
    			<span class="error">${errors["memRegno1"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>주민번호2</th>
    		<td>
    			<input type="text" name="memRegno2" value="${member.memRegno2 }" />
    			<span class="error">${errors["memRegno2"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>생일</th>
    		<td>
    			<input type="date" name="memBir"  value="${member.memBir }" />
    			<span class="error">${errors["memBir"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>우편번호</th>
    		<td>
    			<input type="text" name="memZip"  value="${member.memZip }" />
    			<span class="error">${errors["memZip"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>주소1</th>
    		<td>
    			<input type="text" name="memAdd1"  value="${member.memAdd1 }" />
    			<span class="error">${errors["memAdd1"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>주소2</th>
    		<td>
    			<input type="text" name="memAdd2"  value="${member.memAdd2 }" />
    			<span class="error">${errors["memAdd2"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>집전화번호</th>
    		<td>
    			<input type="text" name="memHometel" value="${member.memHometel }" />
    			<span class="error">${errors["memHometel"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>회사번호</th>
    		<td>
    			<input type="text" name="memComtel" value="${member.memComtel }" />
    			<span class="error">${errors["memComtel"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>휴대폰</th>
    		<td>
    			<input type="text" name="memHp"  value="${member.memHp }" />
    			<span class="error">${errors["memHp"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>이메일</th>
    		<td>
    			<input type="text" name="memMail"  value="${member.memMail }" />
    			<span class="error">${errors["memMail"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>직업</th>
    		<td>
    			<input type="text" name="memJob" value="${member.memJob }" />
    			<span
    			class="error">${errors["memJob"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>취미</th>
    		<td>
    			<input type="text" name="memLike" value="${member.memLike }" />
    			<span
    			class="error">${errors["memLike"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>기념일</th>
    		<td>
    			<input type="text" name="memMemorial" value="${member.memMemorial }" />
    			<span class="error">${errors["memMemorial"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>기념일자</th>
    		<td>
    			<input type="date" name="memMemorialday" value="${member.memMemorialday }" />
    			<span class="error">${errors["memMemorialday"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>마일리지</th>
    		<td>
    			<input type="number" name="memMileage" value="${member.memMileage }" />
    			<span class="error">${errors["memMileage"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<th>탈퇴여부</th>
    		<td>
    			<input type="text" name="memDelete" value="${member.memDelete }" />
    			<span class="error">${errors["memDelete"] }</span>
    		</td>
    	</tr>
    	<tr>
    		<td colspan="2">	
    			<input type="submit" class="btn btn-primary" value="저장" /> 	
    			<input type="reset" class="btn btn-warning" value="취소" />
    		</td>
    	</tr>
    </table>
    </form>


    탈퇴는 추후에 하고 

    추가 수업 

     

    * 회원관리를 위한 Domain Layer
     * 한 사람의 회원에 대한 모든 정보를 가진 객체 
     * 기본정보 + 구매기록(상품들)
     * 
     * MyBatis를 이용한 조인방법
     * 1. 테이블간의 관계성을 메인 테이블을 중심으로 파악.
     * ex) 한명의 회원과 그 사람의 구매기록 조회, 거래처명 동시 조회.
     *  MEMBER(1) CART(N) PROD(N) main테이블은 Member 언제나 1로 놓고 판단 
     *  MEMBER(1) PROD(N) -> 1 : N 한사람이 여러개 상품 조회
     *  PROD(1) BUYER(1)  -> 1 : 1  상품하나당 거래처 1
     * 2. 각 테이블의 스키마를 반영한 VO생성
     *  MEMBER(MemberVO), PROD(ProdVO), BUYER(BuyerVO)
     * 3. 테이블간의 관계성을 VO에 반영.
     *    1:1 ->  ProdVO   has a BuyerVO
     *    1:N  -> has many구조  MemberVO has many ProdVO
     * ----> 2,3번이 되면 ORM구조
     * 4. 조인쿼리 작성 -> resultType대신 resultMap 사용해 바인딩
     *  1:1 -> has a -> association 으로 바인딩
     *  1:N -> has many -> collection으로 바인딩. -> id로 중복여부 판단 설정

     

    <DB구문>

    --b001 사용자의 기본정보와 해당 사용자의 구매 상품 목록을 함께 조회/ --> member
    --구매상품 목록(상품코드, 상품명, 상품분류명, 상품 거래처명, 구매가 ,판매가) -->prod
    -- member와 prod 는 연결성이 없고 중간 관계 테이블인 cart통해서 

    WITH PRODVIEW AS(
    SELECT PROD.*,BUYER_NAME, LPROD_NM
    FROM PROD INNER JOIN BUYER ON(PROD_BUYER = BUYER_ID)
            INNER JOIN LPROD ON(PROD_LGU = LPROD_GU)
    ), CARTVIEW AS(
        SELECT DISTINCT CART_MEMBER, CART_PROD
        FROM CART
    ), CARTPROD AS(
        SELECT  CARTVIEW.*, PRODVIEW.*
        FROM CARTVIEW INNER JOIN PRODVIEW ON (CART_PROD = PROD_ID)
    )
    SELECT MEMBER.*,
        PROD_ID, PROD_NAME, BUYER_NAME, LPROD_NM, PROD_COST, PROD_PRICE
    FROM MEMBER LEFT OUTER JOIN CARTPROD ON (MEM_ID = CART_MEMBER)
    WHERE  MEM_ID = 'b001';

    어떻게 이 데이터를 가져갈것인지 

    resultType=MemverVo prod이런거 못담지 어떻게하면 릴레이션구조를 도메인에 반영할 것이냐 

     

    구매기록담을 수 없어 b001상품여러개 구매 여러건 상품정보 담을 수 있는 property필요 

     

    Project Lombok은 자동으로 편집기에 연결하고 도구를 빌드하여 Java를 향상시키는 Java 라이브러리입니다.

    vo규약 몰라도 vo만들 수 있음 

    <lombok 설치하기>

    플러그인 라이브러리 있어야함 

    먼저 플러그인 다운로드 

    https://projectlombok.org/download

    플러그인

    다운받은것 -> 디드라이브에 옮겨 놓고 그곳에서 cmd창열기 

    lo하고 탭

    java -jar lombok.jar

    Specify location 누르기

    => 실행할 이클립스 선택 

    설치완료확인 하기

    => eclipse ini에서 확인할 수 있다.

    이번엔 라이브러리 추가하기

    => install에서 Maven 누르고 여기 복사해서  pom.xml넣기 

    => 라이브러리 추가됨 

    <!-- javaBean 지원용 -->
    	<dependency>
    	    <groupId>org.projectlombok</groupId>
    		<artifactId>lombok</artifactId>
    		<version>1.18.24</version>
    	</dependency>

     

    아이디를 통해서 동일하다는것 적용 

    @EqualsAndHashCode : 다프로퍼티를 비교해서 같은 상품이라 생각한다.

    @EqualsAndHashCode(of= {"prodId"})

    @ToString

    String 출력을해야하는녀석 안해야하는 녀석 존재 

    긴 내용들은 콘솔에서 출력하다가 퍼포먼스 줄어듬

    @ToString(exclude= {"prodDetail"})  -> 얘는 출력하지마 

    여러개라면 배열처럼 써주면 됨

    지우면 다빠져나감

    @Setter @Getter 대신 @Data를 써도된다.

    @Data 이거써주면 돌아옴 (다 만들어짐)

    자바빈 규약 그래도 알아두기!!!

     

    <MemberVo>

    package kr.or.ddit.vo;
    
    import java.io.Serializable;
    import java.util.List;
    import java.util.Set;
    
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.ToString;
    
    //DTO, marker interface : Serializable - marker annotation
    /**
     * 회원관리를 위한 Domain Layer
     * 한 사람의 회원에 대한 모든 정보를 가진 객체 
     * 기본정보 + 구매기록(상품들)
     */ 
    @Data
    @EqualsAndHashCode(of= {"memId", "memRegno1","memRegno2"})
    @ToString(exclude= {"memPass","memRegno1"," memRegno2","butList"})
    public class MemberVO implements Serializable {
    	
    	private String memId;
    	private transient String memPass;
    	private String memName;
    	private transient String memRegno1;
    	private transient String memRegno2;
    	private String memBir;
    	private String memZip;
    	private String memAdd1;
    	private String memAdd2;
    	private String memHometel;
    	private String memComtel;
    	private String memHp;
    	private String memMail;
    	private String memJob;
    	private String memLike;
    	private String memMemorial;
    	private String memMemorialday;
    	private Integer memMileage;
    	private String memDelete;
    	
    	//구매기록
    	private Set<List<ProdVO>> buyList;
    
    }

     

     

    Member.xml수정중..

    <resultMap type="MemberVO" id="memberMap">
    		<result property="memId" column="MEM_ID"/>
    	</resultMap>

    자동으로 되는걸 수동으로 바꾸는것 

    <resultMap type="MemberVO" id="memberMap" autoMapping="true">
    		
    	</resultMap>

    단순바인딩으로 바꿀 수 있다. 하지만 buyList는 따로 바인딩 해줘야함 

    <resultMap type="MemberVO" id="memberMap" autoMapping="true">
    		<collection property="buyList" javaType="set"></collection>
    	</resultMap>

    collection -has many

    바인딩 해야하는 형태가 컬렉션이면 컬렉션 사용 

    <resultMap type="MemberVO" id="memberMap" autoMapping="true">
    		<collection property="buyList" javaType="hashSet" ofType="ProdVO">
    			<result property="prodId" column="PROD_ID"/>
    		</collection>
    	</resultMap>
        
        oftype적용하면 -- 밑에처럼 됨
        
        <resultMap type="MemberVO" id="memberMap" autoMapping="true">
    		<collection property="buyList" javaType="hashSet" ofType="ProdVO" autoMapping="true">
    		
    		</collection>
    	</resultMap>

    셋을 buyList에 넣어줌 

    ProdVO 같은지 안같은지  판단 암만 set넣어놓고도 equsals만들어놓우묜 언됨 

    <resultMap type="MemberVO" id="memberMap" autoMapping="true">
    		<id property="memId" column="MEM_ID"/>
    		<collection property="buyList" javaType="java.util.HashSet" ofType="ProdVO" autoMapping="true"/>
    
    	</resultMap>

     

    <MemberDaoTest>

    //수정
    	@Test
    	public void testSelectMember() {
    		MemberVO member = dao.selectMember("a001");
    		assertNotNull(member);
    		System.out.println(member);
    		System.out.println(member.getBuyList());
    		
    	}

    <myPage.jsp>

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>	
    <table class="table table-bordered">
    	<tr>
    		<th>회원아이디</th>
    		<td>${member.memId }</td>
    	</tr>
    	<tr>
    		<th>비밀번호</th>
    		<td>${member.memPass }</td>
    	</tr>
    	<tr>
    		<th>회원명</th>
    		<td>${member.memName }</td>
    	</tr>
    	<tr>
    		<th>주민번호1</th>
    		<td>${member.memRegno1 }</td>
    	</tr>
    	<tr>
    		<th>주민번호2</th>
    		<td>${member.memRegno2 }</td>
    	</tr>
    	<tr>
    		<th>생일</th>
    		<td>${member.memBir }</td>
    	</tr>
    	<tr>
    		<th>우편번호</th>
    		<td>${member.memZip }</td>
    	</tr>
    	<tr>
    		<th>주소1</th>
    		<td>${member.memAdd1 }</td>
    	</tr>
    	<tr>
    		<th>주소2</th>
    		<td>${member.memAdd2 }</td>
    	</tr>
    	<tr>
    		<th>집전화번호</th>
    		<td>${member.memHometel }</td>
    	</tr>
    	<tr>
    		<th>회사번호</th>
    		<td>${member.memComtel }</td>
    	</tr>
    	<tr>
    		<th>휴대폰</th>
    		<td>${member.memHp }</td>
    	</tr>
    	<tr>
    		<th>이메일</th>
    		<td>${member.memMail }</td>
    	</tr>
    	<tr>
    		<th>직업</th>
    		<td>${member.memJob }</td>
    	</tr>
    	<tr>
    		<th>취미</th>
    		<td>${member.memLike }</td>
    	</tr>
    	<tr>
    		<th>기념일</th>
    		<td>${member.memMemorial }</td>
    	</tr>
    	<tr>
    		<th>기념일자</th>
    		<td>${member.memMemorialday }</td>
    	</tr>
    	<tr>
    		<th>마일리지</th>
    		<td>${member.memMileage }</td>
    	</tr>
    	<tr>
    		<th>탈퇴여부</th>
    		<td>${member.memDelete }</td>
    	</tr>
    	<tr>
    		<td colspan="2">
    			<input type="button" class="btn btn-primary linkBtn" value="수정" />
    			<input type="button" class="btn btn-danger" value="탈퇴" />
    		</td>
    	</tr>
    	<tr>
    		<th>구매기록</th>
    		<td>
    			<table>
    				<thead>
    					<tr>
    						<th>상품명</th>
    						<th>분류명</th>
    						<th>거래처명</th>
    						<th>구매가</th>
    						<th>판매가</th>
    					</tr>
    				</thead>
    				<tbody>
    					<c:set var="buyList" value="${member.buyList }" />
    					<c:if test="${not empty buyList }">
    						<c:forEach items="${buyList }" var="prod">
    							<tr>
    								<td>${prod.prodName }</td>
    								<td>${prod.lprodNm }</td>
    								<td>${prod.buyer.buyerName }</td>
    								<td>${prod.prodCost }</td>
    								<td>${prod.prodPrice }</td>
    							</tr>
    						</c:forEach>
    					</c:if>
    					<c:if test="${empty buyList }">
    						<tr>
    							<td colspan="5">구매기록이 없음.</td>
    						</tr>
    					</c:if>
    				</tbody>
    			</table>
    		</td>
    	</tr>
    </table>
    
    <script>
    	$(".linkBtn").on("click", function(event){
    		location.href="${cPath}/member/memberUpdate.do";
    	});
    </script>

    <ProdVO>

    package kr.or.ddit.vo;
    
    import java.io.Serializable;
    
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * 상품에 관한 정보를 가진 Domain Layer
     *
     */
    @Data
    //@Setter
    //@Getter
    //of는 equal hashcode의 파라미터처럼 사용됨, 배열
    //Mybatis에서 set형태의 javaType을 사용하려면 equals를 무조건 사용해야함
    @EqualsAndHashCode(of= {"prodId"})
    @ToString(exclude= {"prodDetail"})
    
    public class ProdVO implements Serializable {
    	private String prodId;
    	private String prodName;
    	private String prodLgu;
    	private String lprodNm;   //추가 문제점 거래처에서 가져올 수 있는 데이터 발생하면 또 가져오기 힘듦
    	private String prodBuyer;
    	private BuyerVO buyer; //  추가has a
    	private Integer prodCost;
    	private Integer prodPrice;
    	private Integer prodSale;
    	private String prodOutline;
    	private String prodDetail;
    	private String prodImg;
    	private Integer prodTotalstock;
    	private String prodInsdate;
    	private Integer prodProperstock;
    	private String prodSize;
    	private String prodColor;
    	private String prodDelivery;
    	private String prodUnit;
    	private Integer prodQtyin;
    	private Integer prodQtysale;
    	private Integer prodMileage;
    	
    }

    <BuyerVO>

    package kr.or.ddit.vo;
    
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    /**
     * 거래처에 대한 정보를 가진 Domain Layer
     *
     */
    @Data
    @EqualsAndHashCode(of="buyerId")
    public class BuyerVO {
    	private String buyerId;
    	private String buyerName;
    	private String buyerLgu;
    	private String buyerBank;
    	private String buyerBankno;
    	private String buyerBankname;
    	private String buyerZip;
    	private String buyerAdd1;
    	private String buyerAdd2;
    	private String buyerComtel;
    	private String buyerFax;
    	private String buyerMail;
    	private String buyerCharger;
    	private String buyerTelext;
    }

     

    Member.xml

    <association property="buyer" javaType="BuyerVO" >
    				<result property="buyerName" column="BUYER_NAME"/>
    </association>
    
    
    <association property="buyer" javaType="BuyerVO" autoMapping="true">
    			
    </association>

    <Member.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="kr.or.ddit.member.dao.MemberDAO">
    	<select id="selectMemberForAuth" parameterType="MemberVO" resultType="MemberVO">
    		 SELECT MEM_ID, MEM_PASS, MEM_NAME, MEM_HP, MEM_ADD1  
    		 FROM MEMBER                                          
    		 WHERE MEM_ID = #{memId}  AND MEM_DELETE IS NULL	         
    	</select>
    	<select id="selectMemberList" resultType="MemberVO">
    		SELECT MEM_ID, MEM_NAME, MEM_HP      
    			, MEM_ADD1, MEM_MAIL, MEM_MILEAGE 
    		FROM MEMBER
    		WHERE MEM_DELETE IS NULL	                      
    	</select>
    	
    	<resultMap type="MemberVO" id="memberMap" autoMapping="true">
    		<id property="memId" column="MEM_ID"/>
    		<collection property="buyList" javaType="java.util.HashSet" ofType="ProdVO" autoMapping="true">
    			<association property="buyer" javaType="BuyerVO" autoMapping="true" />
    		</collection>
    	</resultMap>
    	
    	<select id="selectMember" parameterType="string" resultMap="memberMap">
    		WITH PRODVIEW AS (
    		    SELECT PROD.*, BUYER_NAME, LPROD_NM
    		    FROM PROD INNER JOIN BUYER ON(PROD_BUYER = BUYER_ID)
    		        INNER JOIN LPROD ON(PROD_LGU = LPROD_GU)
    		), CARTVIEW AS(
    		    SELECT DISTINCT CART_MEMBER, CART_PROD
    		    FROM CART
    		), CARTPROD AS(
    		    SELECT CARTVIEW.*, PRODVIEW.*
    		    FROM CARTVIEW INNER JOIN PRODVIEW ON (CART_PROD = PROD_ID)   
    		)
    		SELECT 
    			MEM_ID,	    MEM_PASS,	    MEM_NAME,                                 
    		    MEM_REGNO1,	    MEM_REGNO2,	    TO_CHAR(MEM_BIR, 'YYYY-MM-DD') MEM_BIR,   
    		    MEM_ZIP,	    MEM_ADD1,	    MEM_ADD2,                                 
    		    MEM_HOMETEL,	    MEM_COMTEL,	    MEM_HP,                               
    		    MEM_MAIL,	    MEM_JOB,	    MEM_LIKE,                                 
    		    MEM_MEMORIAL,	TO_CHAR(MEM_MEMORIALDAY, 'YYYY-MM-DD') MEM_MEMORIALDAY,   
    		    MEM_MILEAGE,	 MEM_DELETE                                               
    		    , PROD_ID, PROD_NAME, PROD_COST, PROD_PRICE
    		    , BUYER_NAME, LPROD_NM
    		FROM MEMBER LEFT OUTER JOIN CARTPROD ON (MEM_ID = CART_MEMBER)
    		WHERE MEM_ID = #{memId}
    	                                                    
    	</select>
    	<insert id="insertMember" parameterType="MemberVO">
    		INSERT INTO MEMBER (                                                                 
    			MEM_ID
    			,MEM_PASS
    			,MEM_NAME
    			,MEM_REGNO1
    			,MEM_REGNO2
    			,MEM_BIR
    			,MEM_ZIP
    			,MEM_ADD1
    			,MEM_ADD2
    			,MEM_HOMETEL
    			,MEM_COMTEL
    			,MEM_HP
    			,MEM_MAIL
    			,MEM_JOB
    			,MEM_LIKE
    			,MEM_MEMORIAL
    			,MEM_MEMORIALDAY
    			,MEM_MILEAGE
    		) VALUES (                                                                       
    			 #{memId,jdbcType=VARCHAR}
    			, #{memPass,jdbcType=VARCHAR}
    			, #{memName,jdbcType=VARCHAR}
    			, #{memRegno1,jdbcType=VARCHAR}
    			, #{memRegno2,jdbcType=VARCHAR}
    			, TO_DATE(#{memBir,jdbcType=DATE}, 'YYYY-MM-DD')
    			, #{memZip,jdbcType=VARCHAR}
    			, #{memAdd1,jdbcType=VARCHAR}
    			, #{memAdd2,jdbcType=VARCHAR}
    			, #{memHometel,jdbcType=VARCHAR}
    			, #{memComtel,jdbcType=VARCHAR}
    			, #{memHp,jdbcType=VARCHAR}
    			, #{memMail,jdbcType=VARCHAR}
    			, #{memJob,jdbcType=VARCHAR}
    			, #{memLike,jdbcType=VARCHAR}
    			, #{memMemorial,jdbcType=VARCHAR}
    			, TO_DATE(#{memMemorialday,jdbcType=DATE}, 'YYYY-MM-DD')
    			, 1000
    		)		                                                                             
    	</insert>
    	<update id="updateMember" parameterType="MemberVO">
    		UPDATE MEMBER
    		SET
    			MEM_NAME = #{memName,jdbcType=VARCHAR}
    			, MEM_ZIP = #{memZip,jdbcType=CHAR}
    			, MEM_ADD1 = #{memAdd1,jdbcType=VARCHAR}
    			, MEM_ADD2 = #{memAdd2,jdbcType=VARCHAR}
    			, MEM_HOMETEL = #{memHometel,jdbcType=VARCHAR}
    			, MEM_COMTEL = #{memComtel,jdbcType=VARCHAR}
    			, MEM_HP = #{memHp,jdbcType=VARCHAR}
    			, MEM_MAIL = #{memMail,jdbcType=VARCHAR}
    			, MEM_JOB = #{memJob,jdbcType=VARCHAR}
    			, MEM_LIKE = #{memLike,jdbcType=VARCHAR}
    			, MEM_MEMORIAL = #{memMemorial,jdbcType=VARCHAR}
    			, MEM_MEMORIALDAY = #{memMemorialday,jdbcType=DATE}
    		WHERE MEM_ID = #{memId,jdbcType=VARCHAR}
    	</update>
    	<update id="deleteMember" parameterType="string">
    		UPDATE MEMBER
    		SET MEM_DELETE = 'Y'
    		WHERE MEM_ID = #{memId}
    	</update>
    </mapper>

    map안에 has a has many관계로 넣어준것임 

    대부분 ...

    1:1 이너조인 

    1:M 아웃터

    728x90
Designed by Tistory.