본문 바로가기
Programming/JDBC

JDBC(1) 기본 + 응용 + 예외처리

by yoon9i 2024. 4. 3.

4. JDBC 자바 코드
  
   ==> compile checed exception 계열 (비런타임 계열)이다.
       즉 무조건 예외처리해야된다. (try~catch 필수 )
 
   ==> java.sql 패키지 사용됨

    1) mysql 접속 정보

      String driver ="com.mysql.cj.jdbc.Driver";
      String url = "jdbc:mysql://localhost:3306/testdb";
      String userid ="root";
      String passwd = "1234";
 
     * oracle 접속 정보
      String driver ="oracle.jdbc.driver.OracleDriver";
      String url = "jdbc:oracle:thin:@localhost:1521:서비스명";
      String userid ="system|sys";
      String passwd = "1234";

    2) 드라이버 로딩 ( com.mysql.cj.jdbc.Driver  클래스를 객체생성하는 작업 의미 )
      => 이전 처럼 new 사용안함.
         대신 Class.forName(문자열);

          Class.forName(driver); 

    3) Connection 연결

       Connection con =  DriverManager.getConnection(url, userid, passwd);

     
    4) sql문 작성
     ==> 문장끝의 ; 반드시 제외.

      String sql = "select deptno as no, dname, loc from dept";

    
    5) PreparedStatement 얻기 (sql문 전송 담당 객체) 

       PreparedStatement pstmt = con.prepareStatement​( sql);

    
    6) sql 문 전송.


       가. select문 ==> 결과를 테이블 형태로 받음.
                       테이블 객체화: ResultSet

           ResultSet rs  = pstmt.executeQuery();

       나. DML문    ==> 결과를 정수(영향받은 행갯수) 받음.

          int n = pstmt.executeUpdate(); // update,insert,delete


    7) ResultSet 에서 컬럼값 얻기

      while( rs.next() ){ // 행선택

          //열 선택
  int deptno = rs.getInt("no");   // 컬럼헤더|위치(1부터)
          int deptno2 = rs.getInt(1);

  String dname = rs.getString("dname"); // 2
          String loc = rs.getString("loc"); // 3

      }

     8) DBMS 는 외부자원이기 때문에 항상 close() 

         사용한 순서
 Connection con연결
 PreparedStatement  pstmt얻기
 ResultSet rs 얻기


 close 작업은 사용한 역순
           rs.close();
   pstmt.close();
   con.close();


5. sql 문에 실제 데이터 설정하는 방법

   1) 용도
      - INSERT
      - DELETE
      - UPDATE
      - SELECT

   2) select 문에서 설정 예

     예> select *
        from 
where deptno = 실제값;

String sql = "select deptno as no, dname, loc from dept
             where deptno = ? or dname= ?";

         PreparedStatement pstmt = con.prepareStatement(sql);
         // ? 대신에 실제값을 지정 ( ? 을 바인딩 변수라고 부른다 )
 //  pstmt.setXXX( ?순서, 값);
 
            pstmt.setInt( 1, 10 );
    pstmt.setString(2,"개발");

 ResultSet rs =  pstmt.executeQuery();
   rs.getXXX

 

6. DML
 => JDBC는 기본적으로 auto commit 으로 동작된다. (************)
   계좌이체등과 같은 트랜잭션으로 처리해야 되는 작업을 할수 없음.

 

package com.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DeleteTest {

	public static void main(String[] args) {
		// Dept 테이블 조회
		// 1) mysql 접속 정보
		String driver = "com.mysql.cj.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/testdb";
		String userid = "root";
		String passwd = "1234";

		// 2) 드라이버 로딩
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		// 3) Connection 연결
		Connection con = null; // 로컬변수라 초기화필수.
		PreparedStatement pstmt = null;

		try {
			con = DriverManager.getConnection(url, userid, passwd);

			// 4) sql 문 작성 ==> 문장끝의 ; 반드시 제외
			// 여러줄로 사용할때는 꼭 공백을 줘야함.(※)
			String sql = "DELETE FROM dept WHERE deptno=?";

			// 5) PreparedStatement ( : sql 문 전송 담당 객체 ) 얻기
			pstmt = con.prepareStatement(sql);
			
			// ? 대신에 실제값 설정 ( prepareStatement 후 executeQuery 전에 해야함 )
			pstmt.setInt(1, 1);
			//
			
			// 6) sql 문 전송. ==> DML 은 정수로 반환
			int n = pstmt.executeUpdate();
			System.out.println(n + " 개가 삭제됨.");

		
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			// 8. DBMS 는 외부자원이기 때문에 항상 close( )
			// 단, close() 는 사용한 순서 역순으로 작성.
			try {
				if(pstmt!=null)pstmt.close();
				if(con!=null)con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}

	}// end main

}// end class
package com.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class InsertTest {

	public static void main(String[] args) {
		// Dept 테이블 조회
		// 1) mysql 접속 정보
		String driver = "com.mysql.cj.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/testdb";
		String userid = "root";
		String passwd = "1234";

		// 2) 드라이버 로딩
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		// 3) Connection 연결
		Connection con = null; // 로컬변수라 초기화필수.
		PreparedStatement pstmt = null;

		try {
			con = DriverManager.getConnection(url, userid, passwd);

			// 4) sql 문 작성 ==> 문장끝의 ; 반드시 제외
			// 여러줄로 사용할때는 꼭 공백을 줘야함.(※)
			String sql = "INSERT INTO dept (deptno, dname, loc) "
					+ " VALUES ( ?, ? , ? )";

			// 5) PreparedStatement ( : sql 문 전송 담당 객체 ) 얻기
			pstmt = con.prepareStatement(sql);
			
			// ? 대신에 실제값 설정 ( prepareStatement 후 executeQuery 전에 해야함 )
			pstmt.setInt(1, 1);
			pstmt.setString(2, "관리");
			pstmt.setString(3, "부산");
			//
			

			// 6) sql 문 전송. ==> DML 은 정수로 반환
			int n = pstmt.executeUpdate();
			System.out.println(n + " 개가 저장됨.");

		
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			// 8. DBMS 는 외부자원이기 때문에 항상 close( )
			// 단, close() 는 사용한 순서 역순으로 작성.
			try {
				if(pstmt!=null)pstmt.close();
				if(con!=null)con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}

	}// end main

}// end class
package com.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class SelectTest {

	public static void main(String[] args) {

//		// Dept 테이블 조회
//		// 1) mysql 접속 정보
//		String driver = "com.mysql.cj.jdbc.Driver";
//		String url = "jdbc:mysql://localhost:3306/testdb";
//		String userid = "root";
//		String passwd = "1234";
//		
//		// 2) 드라이버 로딩
//		try {
//			Class.forName(driver);
//		} catch (ClassNotFoundException e) {
//			e.printStackTrace();
//		}
//		
//		// 3) Connection 연결
//		Connection con = null; // 로컬변수라 초기화필수.
//		try {
//			con = DriverManager.getConnection( url, userid, passwd );
//		} catch (SQLException e) {
//			e.printStackTrace();
//		}
//		
//		// 4) sql 문 작성 ==> 문장끝의 ; 반드시 제외
//		String sql = "SELECT deptno AS no, dname, loc FROM dept";
//		
//		// 5) PreparedStatement ( : sql 문 전송 담당 객체 ) 얻기
//		try {
//			PreparedStatement pstmt = con.prepareStatement( sql );
//		} catch (SQLException e) {
//			e.printStackTrace();
//		}

		// 정리 ↓ ( 너무많은 try-catch 문이 사용중이기 때문 )

		// Dept 테이블 조회
		// 1) mysql 접속 정보
		String driver = "com.mysql.cj.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/testdb";
		String userid = "root";
		String passwd = "1234";
		
		// 2) 드라이버 로딩
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		// 3) Connection 연결
		Connection con = null; // 로컬변수라 초기화필수.
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);

			// 4) sql 문 작성 ==> 문장끝의 ; 반드시 제외
			// 여러줄로 사용할때는 꼭 공백을 줘야함.(※)
			String sql = "SELECT deptno AS no, dname, loc "
					+ " FROM dept "
					+ " WHERE deptno=? "
					+ " OR dname=?";

			// 5) PreparedStatement ( : sql 문 전송 담당 객체 ) 얻기
			pstmt = con.prepareStatement(sql);
			
			// ? 대신에 실제값 설정 ( prepareStatement 후 executeQuery 전에 해야함 )
			pstmt.setInt(1, 10); // deptno
			pstmt.setString(2, "인사과"); // dname
			

			// 6) sql 문 전송. ==> ResultSet 은 select 한 결과값이고 테이블로 생각하자.
			rs = pstmt.executeQuery();

			// 7) ResultSet 에서 컬럼값 얻기
			while (rs.next()) {

				int deptno = rs.getInt("no"); // 컬럼헤더값
//				int deptno2 = rs.getInt(1); // 컬럼헤더위치값

				String dname = rs.getString(2); // 컬럼헤더위치값
				String loc = rs.getString("loc"); // 컬럼헤더값

				System.out.println(deptno + "\t" + dname + "\t" + loc);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			// 8. DBMS 는 외부자원이기 때문에 항상 close( )
			// 단, close() 는 사용한 순서 역순으로 작성.
			try {
				if(rs!=null)rs.close();
				if(rs!=null)pstmt.close();
				if(rs!=null)con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
	}// end main

}// end class
package com.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class UpdateTest {

	public static void main(String[] args) {
		// Dept 테이블 조회
		// 1) mysql 접속 정보
		String driver = "com.mysql.cj.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/testdb";
		String userid = "root";
		String passwd = "1234";

		// 2) 드라이버 로딩
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		// 3) Connection 연결
		Connection con = null; // 로컬변수라 초기화필수.
		PreparedStatement pstmt = null;

		try {
			con = DriverManager.getConnection(url, userid, passwd);

			// 4) sql 문 작성 ==> 문장끝의 ; 반드시 제외
			// 여러줄로 사용할때는 꼭 공백을 줘야함.(※)
			String sql = "UPDATE dept"
					+ " SET dname=?, loc=?"
					+ " WHERE deptno=?";

			// 5) PreparedStatement ( : sql 문 전송 담당 객체 ) 얻기
			pstmt = con.prepareStatement(sql);
			
			// ? 대신에 실제값 설정 ( prepareStatement 후 executeQuery 전에 해야함 )
			pstmt.setString(1, "개발");
			pstmt.setString(2, "서울");
			pstmt.setInt(3, 1);
			//
			
			// 6) sql 문 전송. ==> DML 은 정수로 반환
			int n = pstmt.executeUpdate();
			System.out.println(n + " 개가 수정됨.");

		
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			// 8. DBMS 는 외부자원이기 때문에 항상 close( )
			// 단, close() 는 사용한 순서 역순으로 작성.
			try {
				if(pstmt!=null)pstmt.close();
				if(con!=null)con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}

	}// end main

}// end class

 

 

 



#############################################################
5. 기능 분리 

  가. 현재상황( 3가지 기능이 하나의 클래스에서 처리되고 있음 )

     SelectTest.java   <----------------------------> MySQL
        main()
     - 화면처리코드(Swing)
     - 비즈니즈로직코드(가공)
     - DB연동코드


   
  나. 기능분리
                           DeptService(인터페이스)
                                |
|
   DeptMain     <---->      DeptServiceImpl       <---->     DeptDAO     <----> MySQL(파일)
    main()  
    화면처리코드                -비즈니즈로직코드(가공)             - DB연동코드
                             -트랜잭션처리(*****)

  - DeptDAO에서 얻은 결과값을 DeptMain에 전달하는 작업을 추가하자.
    하나의 행을 저장하는 클래스를 작성한다. 
    ==> DeptDTO.java

  * 패턴
  DAO 패턴: - Data Access Object 패턴
           - 데이터(DB,파일등)에 접근시 전담하는 클래스

  DTO 패턴: - Data Transfer Object 패턴
           - 일반적으로 테이블당 하나씩 작성해서
     테이블의 하나의 레코드를 저장하는 용도로 사용됨.
     예> dept테이블: DeptDTO.java
        emp테이블: EmpDTO.java

6. 중복 deptno 값 입력시 예외처리
  => 개인적으로 정리하기.

 

* SELECT 기능분리 

package com.jdbc2;

public class DeptMain {

	public static void main(String[] args) {

		// DeptService 연동
		DeptService service = new DeptServiceImpl();
		service.select();
		
	}
}
package com.jdbc2;

//역할: - 메서드 강제, loosely coupling, 어떤 기능인지 쉽게 알 수 있다.
public interface DeptService {
	public void select();
}
package com.jdbc2;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

// 역할: MySQL DB 연동
// DAO 패턴: Data Access Object
public class DeptDAO {

	public void select(Connection con) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			String sql = "select deptno as no, dname, loc from dept";

			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				int deptno = rs.getInt("no"); // 컬럼헤더값
				String dname = rs.getString(2); // 컬럼헤더 위치값
				String loc = rs.getString("loc"); // 컬럼헤더값
				System.out.println(deptno + "\t" + dname + "\t" + loc);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
	}// end select
}
package com.jdbc2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

//역할: -비즈니즈로직코드(가공), -트랜잭션처리(*****)
// Connection con 까지만 얻으면 됨.
public class DeptServiceImpl implements DeptService {

	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/testdb";
	String userid = "root";
	String passwd = "1234";

	// 생성자
	public DeptServiceImpl() {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 메서드
	@Override
	public void select() {
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);

			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			dao.select(con);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
	}// end select

}

 

* SELECT 기능분리 (2)

package com.jdbc3;

import java.util.List;

public class DeptMain {

	public static void main(String[] args) {

		// DeptService 연동
		DeptService service = new DeptServiceImpl();
		List<DeptDTO> list = service.select();
		
		for (DeptDTO dto : list) {
			System.out.println(dto);
		}
	}
}
package com.jdbc3;

import java.util.List;

//역할: - 메서드 강제, loosely coupling, 어떤 기능인지 쉽게 알 수 있다.
public interface DeptService {
	public List<DeptDTO> select();
}
package com.jdbc3;

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

//역할: -비즈니즈로직코드(가공), -트랜잭션처리(*****)
// Connection con 까지만 얻으면 됨.
public class DeptServiceImpl implements DeptService {

	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/testdb";
	String userid = "root";
	String passwd = "1234";

	// 생성자
	public DeptServiceImpl() {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 메서드
	@Override
	public List<DeptDTO> select() {
		Connection con = null;
		List<DeptDTO> list = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);

			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			list = dao.select(con);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		
		return list;
	}// end select

}
package com.jdbc3;

// 역할: dept 테이블의 레코드 저장
public class DeptDTO {

	// 컬럼에 대응하는 변수
	int deptno;
	String dname;
	String loc;
	
	public DeptDTO() {
		
	}

	public DeptDTO(int deptno, String dname, String loc) {
		this.deptno = deptno;
		this.dname = dname;
		this.loc = loc;
	}

	public int getDeptno() {
		return deptno;
	}

	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

	@Override
	public String toString() {
		return "DeptDTO [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
	}
	
	
}
package com.jdbc3;

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

// 역할: MySQL DB 연동
// DAO 패턴: Data Access Object
public class DeptDAO {

	public List<DeptDTO> select(Connection con) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// DTO 누적하는 용도로 ArrayList 를 사용한다.
		List<DeptDTO> list = new ArrayList<>();
		
		try {
			String sql = "SELECT deptno AS no, dname, loc FROM dept";

			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				int deptno = rs.getInt("no"); // 컬럼헤더값
				String dname = rs.getString(2); // 컬럼헤더 위치값
				String loc = rs.getString("loc"); // 컬럼헤더값
//				System.out.println(deptno + "\t" + dname + "\t" + loc);
				
				// DTO 저장하고 누적해야된다.
				DeptDTO dto = new DeptDTO(deptno, dname, loc); // 생성
				list.add(dto); // 누적
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		
		return list;
	}// end select
}

 

# 기능분리 응용 - SELECT, DELETE, INSERT

package com.jdbc4_DML;

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

public class DeptMain {

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);

		while (true) {

			System.out.println("1. 전체목록");
			System.out.println("2. 부서저장");
			System.out.println("3. 삭제");
			System.out.println("0. 종료");
			System.out.println("-------------------");
			String num = scan.next();
			if ("0".equals(num)) {
				System.out.println("프로그램 종료됨.");
				System.exit(0);
			} else if ("1".equals(num)) {
				// DeptService 연동
				DeptService service = new DeptServiceImpl();
				List<DeptDTO> list = service.select();
				for (DeptDTO dto : list) {
					System.out.println(dto);
				}
			} else if ("2".equals(num)) {
				System.out.println("부서번호를 입력하세요.");
				String deptno = scan.next();
				System.out.println("부서명를 입력하세요.");
				String dname = scan.next();
				System.out.println("부서위치를 입력하세요.");
				String loc = scan.next();

				// DTO 저장해서 DAO로 전달
				DeptDTO dto = new DeptDTO(Integer.parseInt(deptno), dname, loc);

				// DeptService 연동
				DeptService service = new DeptServiceImpl();
				int n = service.insert(dto);
				System.out.println(n + " 개가 저장됨.");

			} else if ("3".equals(num)) {
				System.out.println("삭제할 부서번호를 입력하세요.");
				String deptno = scan.next();

				// DeptService 연동
				DeptService service = new DeptServiceImpl();
				int n = service.delete(Integer.parseInt(deptno));
				System.out.println(n + " 개가 삭제됨.");
				
				
			} else {
				System.out.println("번호를 잘못 입력했습니다.");
			}

		} // end while

	}// end main
}// end class
package com.jdbc4_DML;

import java.util.List;

//역할: - 메서드 강제, loosely coupling, 어떤 기능인지 쉽게 알 수 있다.
public interface DeptService {
	
	public List<DeptDTO> select();
	
	public int insert(DeptDTO dto);
	
	public int delete(int deptno);
}
package com.jdbc4_DML;

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

//역할: -비즈니즈로직코드(가공), -트랜잭션처리(*****)
// Connection con 까지만 얻으면 됨.
public class DeptServiceImpl implements DeptService {

	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/testdb";
	String userid = "root";
	String passwd = "1234";

	// 생성자
	public DeptServiceImpl() {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 메서드
	@Override
	public List<DeptDTO> select() {
		List<DeptDTO> list = null;
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);
			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			list = dao.select(con);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return list;
	}// end select

	@Override
	public int insert(DeptDTO dto) {
		int n = 0;
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);
			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			n = dao.insert(con, dto);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}

	@Override
	public int delete(int deptno) {
		int n = 0;
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);
			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			n = dao.delete(con, deptno);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}

}
package com.jdbc4_DML;

// 역할: dept 테이블의 레코드 저장
public class DeptDTO {
	
	// 컬럼에 대응하는 변수
	int deptno;
	String dname;
	String loc;
	
	public DeptDTO() {}

	public DeptDTO(int deptno, String dname, String loc) {
		this.deptno = deptno;
		this.dname = dname;
		this.loc = loc;
	}

	public int getDeptno() {
		return deptno;
	}

	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

	@Override
	public String toString() {
		return "DeptDTO [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
	}
	
    
}
package com.jdbc4_DML;

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

// 역할: MySQL DB 연동
// DAO 패턴: Data Access Object
public class DeptDAO {
	
	// 부서 삭제
	public int delete(Connection con, int deptno) {
		int n = 0;
		PreparedStatement pstmt = null;
		try {
			String sql = "DELETE FROM dept WHERE deptno=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setInt(1, deptno);
			
			n = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}

	// 부서 저장
	public int insert(Connection con, DeptDTO dto) {
		int n = 0;
		PreparedStatement pstmt = null;
		try {
			String sql = "insert into dept ( deptno, dname, loc ) " + " values (?,?,?)";
			pstmt = con.prepareStatement(sql);
			pstmt.setInt(1, dto.getDeptno());
			pstmt.setString(2, dto.getDname());
			pstmt.setString(3, dto.getLoc());
			n = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}// end insert

	// 목록보기
	public List<DeptDTO> select(Connection con) {

		// DTO 누적하는 용도로 ArrayList를 사용한다.
		List<DeptDTO> list = new ArrayList<>();

		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			String sql = "select deptno as no, dname, loc from dept";

			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				int deptno = rs.getInt("no"); // 컬럼헤더값
				String dname = rs.getString(2); // 컬럼헤더 위치값
				String loc = rs.getString("loc"); // 컬럼헤더값
				// DTO 저장하고 누적해야 된다.
				DeptDTO dto = new DeptDTO(deptno, dname, loc);
				list.add(dto);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally

		return list;
	}// end select
}

 

# 기능분리 응용 - SELECT, DELETE, INSERT + 예외처리

package com.jdbc4_DML2_예외처리;

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

public class DeptMain {

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);

		while (true) {

			System.out.println("1. 전체목록");
			System.out.println("2. 부서저장");
			System.out.println("3. 부서삭제");
			System.out.println("0. 종료");
			System.out.println("-------------------");
			String num = scan.next();
			if ("0".equals(num)) {
				System.out.println("프로그램 종료됨.");
				System.exit(0);
			} else if ("1".equals(num)) {
				// DeptService 연동
				DeptService service = new DeptServiceImpl();
				List<DeptDTO> list = service.select();
				for (DeptDTO dto : list) {
					System.out.println(dto);
				}
			} else if ("2".equals(num)) {
				System.out.println("부서번호를 입력하세요.");
				String deptno = scan.next();
				System.out.println("부서명를 입력하세요.");
				String dname = scan.next();
				System.out.println("부서위치를 입력하세요.");
				String loc = scan.next();

				// DTO 저장해서 DAO로 전달
				DeptDTO dto = new DeptDTO(Integer.parseInt(deptno), dname, loc);

				// DeptService 연동
				DeptService service = new DeptServiceImpl();
				int n = 0;
				try {
					n = service.insert(dto);
					System.out.println(n + " 개가 저장됨.");
				} catch (DuplicatedDeptnoException e) {
					System.out.println(e.getMessage());
				}

			} else if ("3".equals(num)) {
				System.out.println("삭제할 부서번호를 입력하세요.");
				String deptno = scan.next();
				// DeptService 연동
				DeptService service = new DeptServiceImpl();
				int n = service.delete(Integer.parseInt(deptno));
				System.out.println(n + " 개가 삭제됨.");
			} else {
				System.out.println("번호를 잘못 입력했습니다.");
			}

		} // end while

	}// end main
}// end class
package com.jdbc4_DML2_예외처리;

import java.util.List;

//역할: - 메서드 강제, loosely coupling, 어떤 기능인지 쉽게 알 수 있다.
public interface DeptService {
	
	public List<DeptDTO> select();
	
	public int insert(DeptDTO dto) throws DuplicatedDeptnoException;
	
	public int delete(int deptno);
}
package com.jdbc4_DML2_예외처리;

public class DuplicatedDeptnoException extends Exception {

	public DuplicatedDeptnoException(String message) {
		super(message);
	}

}
package com.jdbc4_DML2_예외처리;

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

//역할: -비즈니즈로직코드(가공), -트랜잭션처리(*****)
// Connection con 까지만 얻으면 됨.
public class DeptServiceImpl implements DeptService {

	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/testdb";
	String userid = "root";
	String passwd = "1234";

	// 생성자
	public DeptServiceImpl() {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 메서드
	@Override
	public List<DeptDTO> select() {
		List<DeptDTO> list = null;
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);
			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			list = dao.select(con);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return list;
	}// end select

	@Override
	public int insert(DeptDTO dto) throws DuplicatedDeptnoException {
		int n = 0;
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);
			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			n = dao.insert(con, dto);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}

	@Override
	public int delete(int deptno) {
		int n = 0;
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, userid, passwd);
			// DeptDAO 연동
			DeptDAO dao = new DeptDAO();
			n = dao.delete(con, deptno);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}

}
package com.jdbc4_DML2_예외처리;

// 역할: dept 테이블의 레코드 저장
public class DeptDTO {
	
	// 컬럼에 대응하는 변수
	int deptno;
	String dname;
	String loc;
	
	public DeptDTO() {}

	public DeptDTO(int deptno, String dname, String loc) {
		this.deptno = deptno;
		this.dname = dname;
		this.loc = loc;
	}

	public int getDeptno() {
		return deptno;
	}

	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

	@Override
	public String toString() {
		return "DeptDTO [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
	}
	
    
}
package com.jdbc4_DML2_예외처리;

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

// 역할: MySQL DB 연동
// DAO 패턴: Data Access Object
public class DeptDAO {

	// 부서 삭제
	public int delete(Connection con, int deptno) {
		int n = 0;
		PreparedStatement pstmt = null;
		try {
			String sql = "delete from dept where deptno=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setInt(1, deptno);
			n = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}

	// 부서 저장
	public int insert(Connection con, DeptDTO dto) throws DuplicatedDeptnoException {
		int n = 0;
		PreparedStatement pstmt = null;
		try {
			String sql = "insert into dept ( deptno, dname, loc ) " + " values (?,?,?)";
			pstmt = con.prepareStatement(sql);
			pstmt.setInt(1, dto.getDeptno());
			pstmt.setString(2, dto.getDname());
			pstmt.setString(3, dto.getLoc());
			n = pstmt.executeUpdate();
		} catch (SQLException e) {

			// 중복예외처리 클래스를 만들고 명시적으로 생성한다.
			throw new DuplicatedDeptnoException(dto.getDeptno() + " 값이 중복");

		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally
		return n;
	}// end insert

	// 목록보기
	public List<DeptDTO> select(Connection con) {

		// DTO 누적하는 용도로 ArrayList를 사용한다.
		List<DeptDTO> list = new ArrayList<>();

		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			String sql = "select deptno as no, dname, loc from dept";

			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				int deptno = rs.getInt("no"); // 컬럼헤더값
				String dname = rs.getString(2); // 컬럼헤더 위치값
				String loc = rs.getString("loc"); // 컬럼헤더값
				// DTO 저장하고 누적해야 된다.
				DeptDTO dto = new DeptDTO(deptno, dname, loc);
				list.add(dto);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} // end finally

		return list;
	}// end select
}

 

'Programming > JDBC' 카테고리의 다른 글

MyBatis(3) 동적sql 처리  (0) 2024.04.05
MyBatis(2) MyBatis 사용  (0) 2024.04.04
MyBatis(1) 설치 및 설정  (0) 2024.04.04
JDBC(2) 트랜잭션  (0) 2024.04.04
JDBC 설정하는방법  (1) 2024.04.03