기록
  • 1031 jdbc - day2
    2023년 10월 31일 09시 33분 20초에 업로드 된 글입니다.
    작성자: 삶은고구마

    design 패턴 中 mvc 패턴

    mvc 각 클래스 역할을 생각해서 기능을 분배할 것.

    Connetion, PreparedStatement,resultSet은 사용 후 반드시 close

     

    새 프로젝트 생성 시, db를 사용한다면 lib-ojdbc8.jar를 외부클래스 등록할 것, 인코딩 확인.

     


    어제에 이어서 member mvc 재실습

    단, 추가된 class가 있다. (service, JdbcTemplate,MemberException)

    service

    어제는 DAO에 insert기준으로 1~7의 과정을 실행했는데 

    service 클래스를 추가함으로서 dao의 고생을 조금 덜어주었다(?)

     

    JdbcTemplate

    또한, 중복되는 코드는 인자값만 다르게 해서(오버로딩) JdbcTemplate 라는 유틸 클래스에 모아뒀다.

    자원반환할 때 매번 close() try~catch를 사용해도 되지만

    중복되는 것은 따로 빼두는 것이 추후 코드를 수정할 때 편할거같다.

    해당 클래스 초기화블럭에 드라이버 클래스를 등록하여 매번 등록하지 않아도 되는 번거로움이 제거됨.

     

    MemberException

    MemberException이라는 customException을 만든 후

    dao에서 어떤 오류가 발생하는지 예외를 던져 확인하기 편하게 수정하였다.

     

     


     

    sysout으로 출력문을 찍어 흐름을 확인해본 결과 아래와 같았다.

    -각 클래스의 역할이 무엇인지 확인하기

    -흐름 파악이 어려운 구간에 print 출력해서 순서 확인해보기.

    -특히 dql(select) / dml(insert,update,delete)는 비슷하면서도 중간에 코드가 다르기 때문에 차이점을 알아둬야한다.

    select는 excuteQuery를 사용하고 resultSet을 반환,

    나머지는 excuteUpdate를 사용하고 실행된 행의 갯수(int)를 반환.

    dml은 결과값을 받은 후 commit 이나 rollback수행.

     

     


    Main

    더보기
    package com.sh.run;
    
    import com.sh.member.view.MemberMenu;
    
    /**
     * 
     * @author 
     *
     */
    public class Main 
    {
    	public static void main(String[] args) 
    	{
    		new MemberMenu().mainMenu();
    		System.out.println("이용해 주셔서 감사합니다^^");
    	}
    }

     

    MemberMenu

    더보기
    package com.sh.member.view;
    
    import java.sql.Date;
    import java.text.SimpleDateFormat;
    import java.util.List;
    import java.util.Scanner;
    
    import com.sh.member.controller.MemberController;
    import com.sh.member.model.entity.Member;
    
    /**
     * @author 
     * 
     */
    public class MemberMenu {
    	// view 단에서 처리해야하므로 이 클래스에서만 선언한다.
    	private Scanner sc = new Scanner(System.in);
    	//memberController
    	private MemberController mc = new MemberController();
    	
    	
    	public void mainMenu() {
    		String menu = """
    				===== 회원 관리 프로그램2 =====
    				1. 전체조회
    				2. 아이디 조회
    				3. 이름 검색
    				4. 회원 가입
    				5. 회원정보 변경
    				6. 회원탈퇴
    				7. 탈퇴 회원 조회
    				0. 프로그램 종료
    				==========================
    				선택 : """;
    
    		while (true) {
    			System.out.println();
    			System.out.println(menu);
    			String choice = sc.next();
    			
    			Member member = null;
    			List<Member> members = null;
    			String id = null;
    			String name = null;
    			int result = 0;
    			
    			
    			switch (choice) {
    			
    				//전체 조회
    			case "1":
    				members = mc.findAll();
    				displayMembers(members);
    				break;
    				
    				//아이디 조회 (pk값으로 조회하므로, 1명만 조회된다.)
    			case "2":
    				id = inputId();
    				member = mc.findById(id);
    				displayMember(member);
    				break;
    				
    				//이름 검색(여러건이 검색 될 수있어서 list)
    			case "3":
    				name = inputName();
    				members = mc.findByName(name);
    				displayMembers(members);
    				break;
    				
    				//회원가입
    			case "4":
    				member = inputMember();
    				result = mc.insertMember(member);
    				displayResult("회원가입",result);
    				break;
    				
    				
    				//회원정보 변경
    			case "5":
    				updateMenu();
    				break;
    				
    				
    				//회원 탈퇴
    			case "6":
    				id = inputId();
    				result = mc.deleteMember(id); //조회가 되지 않았다면 null반환
    				displayResult("회원탈퇴",result);//결과출력
    				break;
    				
    				//탈퇴한 회원 조회(MEMBER_DEL조회)
    			case "7":	
    				members = mc.findAll_quit();
    				displayMembers(members);
    				break;
    			case "0":
    				return;//Main으로.
    
    			default:
    				System.out.println("잘못 입력하셨습니다..");
    				break;
    			}
    		}
    	}
    
    	private String inputId()
    	{
    		System.out.print(">>아이디를 입력해주세요.");
    		return sc.next();
    	}
    	
    	//사용자 이름 입력
    	private String inputName() {
    		System.out.print(">>조회하실 이름을 입력해주세요.");
    		return sc.next();
    	}
    
    	//dml 처리결과 메소드..
    	private void displayResult(String type, int result) 
    	{
    		if(result>0)
    		{
    			System.out.println(type+" 성공!💞");
    		}
    		else
    		{
    			System.out.println(type+" 실패!(ノ`Д)ノ");
    		}
    	}
    
    	/**
    	 * 회원가입 시 사용자 입력 정보를 
    	 * Member 객체로 반환 하는 메소드
    	 * @return
    	 */
    	private Member inputMember() 
    	{
    		Member member = new Member();
    		System.out.println(">회원 정보를 입력해주세요.");
    		System.out.print(">아이디");
    		member.setId(sc.next());
    		
    		System.out.print("이름");
    		member.setName(sc.next());
    		
    		System.out.print(">성별(M/F)");
    		member.setGender(sc.next());
    		
    		System.out.print(">생일(1999-09-10)");
    		member.setBirthday(Date.valueOf(sc.next())); //yyyy-mm-dd 형식으로만 입력해야함
    		
    		System.out.print(">이메일");
    		member.setEmail(sc.next());
    		
    		//point,CreateAt은 기본값으로 처리.
    		
    		return member;
    	}
    
    	
    	/**
         * n건의 회원조회 결과를 출력
         * @param members
         */
        private void displayMembers(List<Member> members) {
            if(members.isEmpty()) {
                System.out.println("\t\t 조회된 결과가 없습니다.ㅜㅜ...");
            }
            else 
            {
            	System.out.println("--------------------------------------------------------------------------------------");
            	
            	
            	if(members.get(0).getDel_date()!=null)
            	{
            		  System.out.printf("%-10s%-10s%-10s%-10s%-20s%-10s%-20s%-20s\n", 
            	                "ID", "Name", "Gender", "Birthday", "Email", "Point", "CreatedAt" , "DEL_DATE");
            		System.out.println("--------------------------------------------------------------------------------------");
            		for(Member member : members) {
                        System.out.printf("%-10s%-10s%-10s%-10s%-20s%-10s%-20s%-20s\n", 
                                member.getId(), 
                                member.getName(), 
                                member.getGender(), 
                                member.getBirthday(), 
                                member.getEmail(), 
                                member.getPoint(), 
                                new SimpleDateFormat("yyyy-MM-dd HH:mm").format(member.getCreatedAt()),
                                member.getDel_date());
                    }
            	}
            	else
            	{
            		System.out.printf("%-10s%-10s%-10s%-10s%-20s%-10s%-20s\n", 
        	                "ID", "Name", "Gender", "Birthday", "Email", "Point", "CreatedAt");
            		System.out.println("--------------------------------------------------------------------------------------");
            		for(Member member : members) {
                        System.out.printf("%-10s%-10s%-10s%-10s%-20s%-10s%-20s\n", 
                                member.getId(), 
                                member.getName(), 
                                member.getGender(), 
                                member.getBirthday(), 
                                member.getEmail(), 
                                member.getPoint(), 
                                new SimpleDateFormat("yyyy-MM-dd HH:mm").format(member.getCreatedAt()));
                    }
            	}
                
            }
            System.out.println("--------------------------------------------------------------------------------------");
        }
    	
        /**
         * 1030
         * 1건의 회원조회 결과를 출력
         * 
         */
        private void displayMember(Member m) 
    	{
    		if(m == null)
    		{
    			System.out.println("회원을 찾을 수 없습니다.ㅠㅠ");
    		}
    		else
    		{
    			System.out.println("----------------------------------------------");
    
    			System.out.printf("ID: %-10s\n"
    							+ "NAME: %-10s\n"
    							+ "GENDER: %-10s\n"
    							+ "BIRTHDAY: %-10s\n"
    							+ "EMAIL: %-20s\n"
    							+ "POINT: %-10s\n"
    							+ "CREATED_AT: %-20s\n",
    					m.getId(),
    					m.getName(),
    					m.getGender(),
    					m.getBirthday(),
    					m.getEmail(),
    					m.getPoint(),
    					new SimpleDateFormat("yyyy-MM-dd HH:mm").format(m.getCreatedAt())
    					
    					);
    			System.out.println("----------------------------------------------");
    		}
    	}
        
        //회원 수정메뉴
        //이름,성별,생일,이메일
        private void updateMenu() {
    		String menu = """
    				=========== 회원 정보수정 ===========
    				1. 이름수정
    				2. 생일수정
    				3. 이메일수정
    				0. 메인메뉴로 돌아가기
    				==================================
    				선택 : """;
    		String id = inputId();
    
    		while(true) {
    			Member member = mc.findById(id);
    			displayMember(member);
    			if(member == null)
    				return; // 메인메뉴로 돌아감.
    
    			System.out.print(menu);
    			String choice = sc.next();
    			int result = 0;
    			switch(choice) {
    			case "1" : 
    				System.out.print("변경할 이름 : ");
    				String newName = sc.next();
    				
    				result = mc.updateMember(id, newName ,0);
    				System.out.println("회원명 수정 성공!");
    				break;
    			case "2" : 
    				System.out.print("변경할 생일 (1999-09-09) : ");
    				//Date newBirthday = Date.valueOf(sc.next());
    				String newBirthday = sc.next();
    				result = mc.updateMember(id, newBirthday,1);
    				System.out.println("생일 수정 성공!");
    				break;
    			case "3" : 
    				System.out.print("변경할 이메일 : ");
    				String newEmail = sc.next();
    				result = mc.updateMember(id, newEmail,2);
    				System.out.println("이메일 수정 성공!");
    				break;
    
    			case "0" : return;
    			default: System.out.println("> 잘못 입력하셨습니다.");
    			}
    
    		}
    
    
    	}
        
    }

     

    MemberController

    더보기
    package com.sh.member.controller;
    
    import java.util.List;
    
    import com.sh.member.model.entity.Member;
    import com.sh.member.model.service.MemberService;
    
    //오늘은 dao에 직접이 아닌, service를 통해 요청
    /**
     * Controller에서는 업무로직담당(Service)에게 업무를 위임.
     *
     */
    public class MemberController 
    {
    	private MemberService ms = new MemberService();
    
    	//회원추가 dml
    	public int insertMember(Member member) 
    	{
    		
    		return ms.insertMember(member);
    	}
    
    	//회원탈퇴 dml
    	public int deleteMember(String id) 
    	{
    		
    		return ms.deleteMember(id);
    	}
    		
    	
    	//이름검색
    	public List<Member> findByName(String name) 
    	{
    		
    		return ms.findByName(name);
    	}
    
    
    	//ID로 조회
    	public Member findById(String id) 
    	{
    		return ms.findById(id);
    	}
    
    	//회원 전체 조회
    	public List<Member> findAll() {
    		return ms.findAll();
    	}
    
    	//탈퇴한 회원 전체 조회
    	public List<Member> findAll_quit() {
    		
    		return ms.findAll_quit();
    	}
    
    	
    	//회원 수정 회원아이디,수정할 내역
    	public int updateMember(String id, String updateData,int type) 
    	{
    		// TODO Auto-generated method stub
    		return ms.updateMember(id,updateData,type);
    	}
    	
    	
    
    }

     

    MemberService

    더보기
    package com.sh.member.model.service;
    
    //static 자원(필드/메소드) import
    //JdbcTemplate클래스의 모든 자원을 import한다는 뜻
    import static com.sh.common.JdbcTemplate.*; 
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.List;
    
    import com.sh.common.JdbcTemplate;
    import com.sh.member.model.dao.MemberDao;
    import com.sh.member.model.entity.Member;
    
    
    /**
     * <pre>
     * dml 처리 절차
     * 1.드라이버 클래스 등록(최초1회)
     * 2.Connection 생성 (url,user,password) - autoCommit false 설정
     * 3.PreparedStatement 객체 생성 (sql) - 미완성 쿼리 값 대입
     * 4.쿼리 실행 pstmt.executeUpdate():int
     * 5.트랜잭션처리
     * 6.자원반납
     * =>1일차에는 dao에서 모두 처리함.
     * =>오늘은 역할을 분담
     * 
     * -Service 단
     * 1.Connection 생성 (url,user,password) - autoCommit false 설정
     * 2.dao요청
     * 3.트랜잭션처리
     * 4.자원반납(conn) - 각 클래스에서 생성한 것만 반환
     * 
     * 
     * -Dao단
     * 1.PreparedStatement 객체 생성 (sql) - 미완성 쿼리 값 대입
     * 2.쿼리 실행 pstmt.executeUpdate():int
     * 3.자원반납(pstmt) - 각 클래스에서 생성한 것만 반환
     * 
     * ===============================================================
     * 
     * dql 처리 절차
     * 1.드라이버 클래스 등록(최초1회)
     * 2.Connection 생성 (url,user,password)
     * 3.PreparedStatement 객체 생성 (query) - 미완성 쿼리 값 대입
     * 4.쿼리 실행 pstmt.executeQuery():resultSet
     * 5.resultSet 처리
     * 6.자원반납
     * 
     * -Service 단
     * 1.Connection 생성
     * 2.dao요청
     * 3.자원반납(conn) - 각 클래스에서 생성한 것만 반환
     * 
     * 
     * -Dao단
     * 1.PreparedStatement 객체 생성 (query) - 미완성 쿼리 값 대입
     * 2.쿼리 실행 pstmt.executeQuery():resultSet
     * 3.resultSet 처리
     * 4.반환(resultSet, PreparedStatement)
     */
    
    public class MemberService 
    {
    	private MemberDao dao = new MemberDao();
    	private String url = "jdbc:oracle:thin:@localhost:1521:xe";
    	private String user="student";
    	private String password="student";
    	
    	public int insertMember(Member member) 
    	{
    		
    		int result=0;
    		 //1.Connection 생성 (url,user,password) - autoCommit false 설정
    		//Connection conn= JdbcTemplate.getConnection(); ->임포트시 클래스명 생략가능
    		System.out.println("1)in MemberService - getConnection");
    		Connection conn= getConnection();
    		try 
    		{
    			//2.dao 요청
    			System.out.println("2)in MemberService - DAO에 요청");
    			result = dao.insertMember(conn,member);
    			//3.트랜잭션처리
    			commit(conn);
    			System.out.println("6)in MemberService - 트랜잭션 처리");
    		}
    		catch (Exception e) 
    		{
    			rollback(conn);//만약 에러가 난다면 롤백
    			e.printStackTrace();
    		}
    		finally
    		{
    			//4.자원반납(conn) - 각 클래스에서 생성한 것만 반환
    			System.out.println("7)in MemberService - 자원반납");
    			close(conn);
    		}
    		
    		return result;
    	}
    
    	//이름검색 dql
    	public List<Member> findByName(String name) 
    	{ 
    		//1.Connection 생성
    		Connection conn = getConnection();
    		//2.dao요청
    		List<Member> members = dao.findByName(conn,name);
    		//3.자원반납(conn) 
    		try 
    		{
    			conn.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    		return members;
    	}
    
    	//id로 조회 dql 
    	//매개변수인 id로 조회를한다.
    	public Member findById(String id) 
    	{
    		//1.Connection 생성
    		Connection conn = getConnection();
    		//2.dao에 요청
    		Member member = dao.findById(conn,id);
    		//3.자원반납(conn) 
    		try 
    		{
    			conn.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    
    		return member; //리턴값은 member 객체 하나
    	}
    	
    	//회원 전체 조회
    	public List<Member> findAll() 
    	{
    		//1.Connection 생성
    		Connection conn = getConnection();
    		//2.dao에 요청
    		List<Member> members = dao.findAll(conn);
    		//3.자원반납(conn) 
    		try 
    		{
    			conn.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    		return members; //리턴값은 member 객체 하나
    	}
    
    	//회원 탈퇴 dml
    	public int deleteMember(String id) 
    	{
    		int result = 0;
    		//1.Connection 생성 
    		Connection conn = getConnection();
    		try {
    			//2.dao요청
    			result = dao.deleteMember(conn,id);
    			//3.트랜잭션처리
    			commit(conn);
    		}
    		catch(Exception e)
    		{
    			//실패했을 경우 롤백
    			rollback(conn);
    		}
    		finally
    		{
    			//4.자원반납(conn)
    			close(conn);
    		}
    		return result;
    	}
    
    	//탈퇴한 회원 조회
    	public List<Member> findAll_quit() 
    	{
    		//1.Connection 생성
    		Connection conn = getConnection();
    		//2.dao에 요청
    		List<Member> members = dao.findAll_quit(conn);
    		//3.자원반납(conn) 
    		try 
    		{
    			conn.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    		return members; //리턴값은 member 객체 하나
    	}
    
    	//회원 수정
    	public int updateMember(String id, String updateData, int type) 
    	{
    		
    		int result = 0;
    		//1.Connection 생성 
    		Connection conn = getConnection();
    		try {
    			//2.dao요청
    			result = dao.updateMember(conn,id,updateData,type);
    			//3.트랜잭션처리
    			commit(conn);
    		}
    		catch(Exception e)
    		{
    			//실패했을 경우 롤백
    			rollback(conn);
    		}
    		finally
    		{
    			//4.자원반납(conn)
    			close(conn);
    		}
    		return result;
    	}
    }

     

    MemberDao

    더보기
    package com.sh.member.model.dao;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.sh.member.model.entity.Member;
    import com.sh.member.model.exception.MemberException;
    
    public class MemberDao {
    
    	public int insertMember(Connection conn, Member member) 
    	{
    		System.out.println("3)in insertMember 메서드 시작");
    		int result=0;
    		String sql = """
    					insert into member values(?,?,?,?,?,default,default)
    					""";
    		
    		//1.PreparedStatement 객체 생성 (sql) - 미완성 쿼리 값 대입
    		try(
    				PreparedStatement pstmt = conn.prepareStatement(sql))
    		{
    			pstmt.setString(1, member.getId());
    			pstmt.setString(2, member.getName());
    			pstmt.setString(3, member.getGender());
    			pstmt.setDate(4, member.getBirthday());
    			pstmt.setString(5, member.getEmail());
    			
    			//2.쿼리 실행 pstmt.executeUpdate():int
    			result = pstmt.executeUpdate();
    			System.out.println("4)in insertMember - 쿼리 실행");
    		} 
    		catch (SQLException e) 
    		{
    			//unchecked 예외로 전환 후 예외 던져주기
    			throw new MemberException("회원 가입 오류",e);
    		}
    		//3.자원반납(pstmt) - 각 클래스에서 생성한 것만 반환 try resource로 해결
    		System.out.println("5)in insertMember - 자원 반납");
    		return result;
    	}
    
    	//이름으로 검색
    	public List<Member> findByName(Connection conn,String name) 
    	{
    		List<Member> members = new ArrayList<>();
    		String sql = "select * from member where name like ?";
    		//1.PreparedStatement 객체 생성 (query) - 미완성 쿼리 값 대입
    		try(
    			PreparedStatement pstmt = conn.prepareStatement(sql))
    		{
    			pstmt.setString(1,"%"+name+"%");
    			//2.쿼리 실행 pstmt.executeQuery():resultSet
    			try(
    					ResultSet rset = pstmt.executeQuery())
    			{
    				//3.resultSet 처리
    				while(rset.next())
    				{
    					//Member member = handleMemberResultSet(rset);
    					//members.add(member);
    					
    					//위의 두줄 코드 합쳐서
    					members.add(handleMemberResultSet(rset));//리스트에 추가한다.
    				}
    			}
    
    			//4.반환(resultSet, PreparedStatement)
    			//위에 try resource구문에서 선언하였으므로 반환은 자동.
    		} 
    		catch (SQLException e) 
    		{
    			//dao 캐치에서는 e 메시지 대신에 throw를..
    			throw new MemberException("회원이름검색 오류..!",e);
    		}
    		return members;
    	}
    
    	private Member handleMemberResultSet(ResultSet rset) throws SQLException {
    		Member member = new Member();
    		member.setId(rset.getString("id"));
    		member.setName(rset.getString("name"));
    		member.setGender(rset.getString("gender"));
    		member.setBirthday(rset.getDate("birthday"));
    		member.setEmail(rset.getString("email"));
    		member.setPoint(rset.getInt("point"));
    		member.setCreatedAt(rset.getTimestamp("created_at"));
    		return member;
    	}
    	
    	//탈퇴한 회원들의 resultSet
    	private Member handleMember_quit_ResultSet(ResultSet rset) throws SQLException {
    		Member member = new Member();
    		member.setId(rset.getString("id"));
    		member.setName(rset.getString("name"));
    		member.setGender(rset.getString("gender"));
    		member.setBirthday(rset.getDate("birthday"));
    		member.setEmail(rset.getString("email"));
    		member.setPoint(rset.getInt("point"));
    		member.setCreatedAt(rset.getTimestamp("created_at"));
    		member.setDel_date(rset.getDate("del_date"));
    		return member;
    	}
    
    	//1030 id로 회원 조회
    	public Member findById(Connection conn, String id) 
    	{
    		//단일값이므로 member
    		Member member = null;
    		
    		String sql = "select * from member where id = ? ";
    		//1.PreparedStatement 객체 생성 (query) - 미완성 쿼리 값 대입
    		try(
    			PreparedStatement pstmt = conn.prepareStatement(sql))
    		{
    			pstmt.setString(1,id);//매개인자[변수]로 받아온 id를 ?에 대입한다.
    			//2.쿼리 실행 pstmt.executeQuery():resultSet
    			try(
    					ResultSet rset = pstmt.executeQuery())
    			{
    				//3.resultSet 처리
    				while(rset.next())
    				{
    					member = handleMemberResultSet(rset);
    				}
    			}
    			//4.반환(resultSet, PreparedStatement)
    			//위에 try resource구문에서 선언하였으므로 반환은 자동.
    		} 
    		catch (SQLException e) 
    		{
    			//dao 캐치에서는 e 메시지 대신에 throw를..
    			throw new MemberException("회원 아이디 검색 오류..!",e);
    		}
    		return member;
    	}
    	
    	
    	//1030 전체 회원 조회
    	public List<Member> findAll(Connection conn) 
    	{
    		List<Member> members = new ArrayList<>();
    		String sql = "select * from member";
    		try(
    			PreparedStatement pstmt = conn.prepareStatement(sql))
    		{
    
    			//2.쿼리 실행 pstmt.executeQuery():resultSet
    			try(
    					ResultSet rset = pstmt.executeQuery())
    			{
    				//3.resultSet 처리
    				while(rset.next())
    				{
    					members.add(handleMemberResultSet(rset));//리스트에 추가한다.
    				}
    			}
    
    		} 
    		catch (SQLException e) 
    		{
    			//dao 캐치에서는 e 메시지 대신에 throw를..
    			throw new MemberException("회원 전체 조회 오류..!",e);
    		}
    		return members;
    	}
    
    	//dml - 회원탈퇴(삭제)
    	public int deleteMember(Connection conn, String id) 
    	{
    		System.out.println("dao - deleteMember");
    		int result = 0;
    		String sql = "delete from member where id = ?";
    		//1.PreparedStatement 객체 생성 (sql) - 미완성 쿼리 값 대입
    		try(
    				PreparedStatement pstmt = conn.prepareStatement(sql);
    				)
    		{
    			//2.쿼리 실행 pstmt.executeUpdate():int
    			pstmt.setString(1, id);
    			result = pstmt.executeUpdate();
    		}
    		catch(SQLException e)
    		{
    			//쿼리 실행시 익셉션 발생시 throw
    			throw new MemberException("회원 삭제(탈퇴) 오류",e);
    		}
    		//3.자원반납(pstmt) - 각 클래스에서 생성한 것만 반환 
    		//try resource라 자동 할당해제
    		return result;
    	}
    
    	//탈퇴한 회원 조회
    	public List<Member> findAll_quit(Connection conn) {
    		List<Member> members = new ArrayList<>();
    		String sql = "select * from member_del";
    		try(
    			PreparedStatement pstmt = conn.prepareStatement(sql))
    		{
    
    			//2.쿼리 실행 pstmt.executeQuery():resultSet
    			try(
    					ResultSet rset = pstmt.executeQuery())
    			{
    				//3.resultSet 처리
    				while(rset.next())
    				{
    					members.add(handleMember_quit_ResultSet(rset));//리스트에 추가한다.
    				}
    			}
    
    		} 
    		catch (SQLException e) 
    		{
    			//dao 캐치에서는 e 메시지 대신에 throw를..
    			throw new MemberException("탈퇴 회원 전체 조회 오류..!",e);
    		}
    		return members;
    	}
    
    	
    	public int updateMember(Connection conn, String id, String updateData, int type) {
    		//0:이름,1:생일,2:이메일 수정
    		String[] typeArray = {"name","birthday","email"};
    		
    		int result=0;
    		String sql = "update member set "+typeArray[type]+" =? where id = ?";
    		//1.PreparedStatement 객체 생성 (sql) - 미완성 쿼리 값 대입
    		try(
    				PreparedStatement pstmt = conn.prepareStatement(sql);
    				)
    		{
    			//2.쿼리 실행 pstmt.executeUpdate():int
    			pstmt.setString(1, updateData);
    			pstmt.setString(2, id);
    			result = pstmt.executeUpdate();
    		}
    		catch(SQLException e)
    		{
    			//쿼리 실행시 익셉션 발생시 throw
    			throw new MemberException("회원 수정:"+ typeArray[type] + " 오류",e);
    		}
    		//3.자원반납(pstmt) - 각 클래스에서 생성한 것만 반환 
    		//try resource라 자동 할당해제
    		return result;
    	}
    
    }

    중복되는 특정 블럭의 코드를 메소드로 만드는 방법

    (handleMemberResultSet)

     

    Member

    더보기
    package com.sh.member.model.entity;
    
    import java.sql.Date;
    import java.sql.Timestamp;
    
    /**
     * db member 테이블과 1대1 매칭하는 클래스
     *  - table - entity class
     *  - column - field
     *  - row - member객체
     *
     */
    public class Member 
    {
    	//멤버sql의 컬럼값을 필드로..
    	private String id;
    	private String name;
    	private String gender;
    	private Date birthday;
    	private String email;
    	private int point;
    	private Timestamp createdAt;
    	private Date del_date; //탈퇴일
    	public Member() {}
    	
    	public Member(String id,String name,String gender, Date birthday, 
    				String email,int point,Timestamp createdAt,Date del_date) 
    	{
    		this.id = id;
    		this.name = name;
    		this.gender = gender;
    		this.birthday = birthday;
    		this.email = email;
    		this.point = point;
    		this.createdAt = createdAt;
    		this.del_date = del_date;
    	}
    
    	public Date getDel_date() {
    		return del_date;
    	}
    	public void setDel_date(Date del_date) {
    		this.del_date = del_date;
    	}
    	
    	public String getId() {
    		return id;
    	}
    	public void setId(String id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getGender() {
    		return gender;
    	}
    	public void setGender(String gender) {
    		this.gender = gender;
    	}
    	public Date getBirthday() {
    		return birthday;
    	}
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    	public String getEmail() {
    		return email;
    	}
    	public void setEmail(String email) {
    		this.email = email;
    	}
    	public int getPoint() {
    		return point;
    	}
    	public void setPoint(int point) {
    		this.point = point;
    	}
    	public Timestamp getCreatedAt() {
    		return createdAt;
    	}
    	
    	@Override
    	public String toString() {
    		return "Member [id=" + id + ", name=" + name + ", gender=" + gender + ", birthday=" + birthday + ", email="
    				+ email + ", point=" + point + ", createdAt=" + createdAt + "]";
    	}
    
    	public void setCreatedAt(Timestamp createdAt) {
    		this.createdAt = createdAt;
    	}
    	
    }

     

    MemberException

    더보기
    package com.sh.member.model.exception;
    
    
    
    //custom exception
    public class MemberException extends RuntimeException {
    
    	public MemberException() {
    		// TODO Auto-generated constructor stub
    	}
    
    	public MemberException(String message) {
    		super(message);
    		// TODO Auto-generated constructor stub
    	}
    
    	public MemberException(Throwable cause) {
    		super(cause);
    		// TODO Auto-generated constructor stub
    	}
    
    	public MemberException(String message, Throwable cause) {
    		super(message, cause);
    		// TODO Auto-generated constructor stub
    	}
    
    	public MemberException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    		super(message, cause, enableSuppression, writableStackTrace);
    		// TODO Auto-generated constructor stub
    	}
    
    }

     

    JdbcTemplate

    더보기
    package com.sh.common;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /**
     * jdbc 관련 공통메소드를 static으로 제공
     * -미리 예외처리 해서 호출부쪽에서 간결히 사용하도록 함.
     * 
     * 역할
     * -드라이버 클래스 등록(최초1회만 하면 ok)
     * -getConnection():Connection
     * -commit(Connection)
     * -rollback(Connection)
     * -close(Connection)
     * -close(PreparedStatement)
     * -close(ResultSet)
     * ==>close() 오버로딩
     */
    public class JdbcTemplate 
    {
    	static String driverClassName = "oracle.jdbc.OracleDriver";
    	static String url = "jdbc:oracle:thin:@localhost:1521:xe"; //접속 프로토콜@url:port
    	static String user = "student";
    	static String password = "student";
    	
    	//이 클래스를 처음 사용할때 초기화블럭이 실행된다.
    	
    	//초기화블럭
    	static
    	{	
    		System.out.println("JdbcTemplate 초기화 블럭");
    		//드라이버 클래스 등록
    		try 
    		{
    			Class.forName(driverClassName);
    		} 
    		catch (ClassNotFoundException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	//커넥션
    	public static Connection getConnection()
    	{
    		Connection conn=null;
    		try 
    		{
    			conn = DriverManager.getConnection(url, user, password);
    			conn.setAutoCommit(false);
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    		return conn;
    	}
    	
    	//커밋
    	public static void commit(Connection conn)
    	{
    		try 
    		{
    			//한번 검사해주기(커넥션이 널이 아니고,닫힌상태가 아니라면)
    			if(conn!=null && !conn.isClosed())
    			conn.commit();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	//롤백
    	public static void rollback(Connection conn)
    	{
    		try 
    		{
    			//한번 검사해주기(커넥션이 널이 아니고,닫힌상태가 아니라면)
    			if(conn!=null && !conn.isClosed())
    			conn.rollback();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	//커넥션 반환
    	public static void close(Connection conn)
    	{
    		try 
    		{
    			//한번 검사해주기(커넥션이 널이 아니고,닫힌상태가 아니라면)
    			if(conn!=null && !conn.isClosed())
    			conn.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	//PreparedStatement 반환
    	public static void close(PreparedStatement pstmt)
    	{
    		try 
    		{
    			//한번 검사해주기(널이 아니고,닫힌상태가 아니라면)
    			if(pstmt!=null && !pstmt.isClosed())
    				pstmt.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	//resultSet 반환
    	public static void close(ResultSet rset)
    	{
    		try 
    		{
    			//한번 검사해주기(널이 아니고,닫힌상태가 아니라면)
    			if(rset!=null && !rset.isClosed())
    				rset.close();
    		} 
    		catch (SQLException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    }

     

    +

    트리거 예제

    /*
    1030 실습과제
    member 테이블에서 삭제(탈퇴)한 회원들관리
    1.member_del (기존 member 모든 컬럼 + del_date(탈퇴일)컬럼 추가)
    2.삭제시 insert 이벤트가 발생하도록 trigger를 생성 TRIG_DELETE_MEMBER
    */
    
    --drop table member_del;
    --1.member_del 테이블을 생성한다.(컬럼만 복사!)
    CREATE TABLE member_del AS
    SELECT * FROM member
    WHERE 1=2;
    alter table member_del add del_date date default sysdate;
    
    --1.5 잘만들어졌나 확인해보자
    select * from member_del;
    select * from member;
    --2.기존 member table에서 데이터가 삭제 될 때 실행되는 trigger 생성
    create or replace trigger TRIG_DELETE_MEMBER
        after
        delete on MEMBER 
        for each row
    begin
            if deleting then --delete 일때 true인 속성
             insert into --MEMBER_DEL 테이블에 insert한다.
                        MEMBER_DEL(ID,NAME,GENDER,BIRTHDAY,EMAIL,POINT,CREATED_AT,DEL_DATE)
                values (
                        :old.ID,
                        :old.NAME,
                        :old.GENDER,
                        :old.BIRTHDAY,
                        :old.EMAIL,
                        :old.POINT,
                        :old.CREATED_AT,
                        sysdate);      
        end if;
    end;
    /

    '공부 > 학습' 카테고리의 다른 글

    1102 jdbc - day4  (0) 2023.11.02
    1101 jdbc - day3  (0) 2023.11.01
    1030 jdbc -day1  (0) 2023.10.30
    1027 (29일차) - sql 9일차  (0) 2023.10.27
    1026 (28일차) -sql 8일  (0) 2023.10.26
    댓글