JDBC - test 코드 작성하기 (list, view, write, update, increase, delete)

Luna·2022년 12월 26일
0

EZEN

목록 보기
11/40

JDBC

  • Java Database Connection
  • Database는 oracle 11g를 쓴다.
  • 프로젝트 이름 : ch16jdbc

시작하기

  1. 라이브러리 안에 프로그램이 들어와 있어야 사용 가능하다.

  2. Oracle이나 MySQL이나 MSSQL 등 어떤걸로 구현할 지 모르니까 Interface로 만들어져 있다.

  3. C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib 로 들어가서 ojdbc6 복사해서 진행할 프로젝트에 붙여넣기 해준다.

  4. 복사 붙여넣기 했다고 라이브러리가 등록된 것이 아니다.

  5. Add Jars`를 눌러서 라이브러리를 등록 해 줘야 한다.

  6. 자바에서 오라클에 전달 하는 실행 객체를 하나 만들어서 쿼리를 넣어 줘야 한다.


실습

List

 package ch16jdbc;

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

// JDBC테스트 클래스 - DAO의 list메서드에 해당한다.
// 메인 만들기 -> 접속 객체 만들기 -> DBA가 접속 -> 나머지 팀원들 접속
public class ListTestMain {

	// 모든 과정에서 오류가 발생 할 수 있으므로 예외처리를 꼭 해줘야 한다.
	// 단계적으로 출력해서 확인.
	// 1~6번까지 예외처리(모든 예외 Exception)를 해줘야 하고 7번은 finally 처리 한다.
	// 하나가 안나오면 바로 위에서 오류가 난 것 이므로 잘 잡아야 한다.
	public static void main(String[] args) {

		// 사용할 객체 선언 - oracle.jdbc 안에 들어있는 인터페이스들(Connection, PreparedStatemen,
		// ResultSet) 사용
		// try문 안에 넣으면 지역변수라서 finally문에서도 사용하기 위헤 try문 안에 선언 했던걸 밖으로 빼줘야 한다.
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null; // select 쿼리문 실행 할때만 사용. insert, update, delete는 integer가 나온다.
		System.out.println("** 사용할 객체 선언 완료. **");

		try {
			// 1~2번은 계속 중복되니까 분할해서 메서드 하나 생성해서 갖다쓸 수 있도록 해야 된다. - 중복 코드 제거하기

			// 1. 드라이버 확인 - oracle.jdbc -> OracleDriver
//			Class.forName("oracle.jdbc.OracleDriver"); // 아래 드라이버 프로그램과 같다.
			Class.forName("oracle.jdbc.driver.OracleDriver"); // 둘 중에 실행되는 걸로 쓰면 된다.
			System.out.println("1. 드라이버가 존재합니다.");

			// 2. 접속(Connection) - 서버위치(localhost), 아이디, 패스워드 필요
			// 서버위치 - Oracle 속성 눌러서 나오는 정보. jdbc:oracle:thin:@호스트이름:포트:SID
			con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "java", "java");
			System.out.println("2. 접속이 잘 되었습니다.");

			// 3. 실행할 할 수 있는 SQL 작성 - SQL Developer에서 실습한 SQL 문장 - ;(세미콜론) 쓰지 않음. 쓰면 오류남.
			// 운영쿼리에 있는 list 운영 쿼리 가져오기. ;(세미콜론)은 넣지 않기. 변경해야 할 데이터는 ?(물음표)로 작성한다.
			// SQL Developer에 있는 쿼리문 그대로 복붙하면 되므로 대소문자 구분 안함~_~
			String sql = "SELECT no, title, writer, writeDate, hit FROM board ORDER BY no DESC";
			System.out.println("3. 실행할 수 있는 sql 작성 - sql = " + sql);

			// 4. 실행 객체 - 작성한 SQL을 Oracle DB에 전달하기 위한 실행 객체 & ?에 대한 데이터 세팅
			// ? -> 게시판 보기를 할 때 where no = 2 -> 2번이 계속 바뀌므로 그 자리에 ?를 넣으면 된다.
			// 현재는 변경할 데이터가 없으므로 그냥 쓴다.
			pstmt = con.prepareStatement(sql);
			System.out.println("4. 실행 객체 완성");

			// 5. 실행
			rs = pstmt.executeQuery(); // select - executeQuery(), insert, update, delete - executeUpdate()
			System.out.println("5. 여러개의 데이터 가져오기 성공");

			// 6. 실행 된 결과를 가지고 리턴된 데이터를 저장 또는 표시 - List에 VO 데이터를 생성해서 담은 데이터를 추가 해야 한다.
			// List 생성 - ListVO에 데이터담기 -> 담은 데이터 추가 하기 / 지금은 담지는 않고 표시만 하는걸로 출력한다.
			// re.next() - 다음 데이터가 존재하면 true를 리턴해주고 다음 데이터로 포인터를 이동. 존재하지 않을 때는 false를 리턴하고
			// while문을 빠져나감.
			// if문장 붙여서 rs가 null이면(rs 실행에 문제가 생기면) while문을 실행하지 않는 코드 추가하기.
			if (rs != null) {
				System.out.println("-------------------------------------------");
				while (rs.next()) {
					System.out.print(rs.getLong("no")); // 순서와 상관없이 출력하려면 이름을 쓴다.
					System.out.print(" | " + rs.getString("title")); // VO에서는 setTitle, 가져올때는 타입으로 가져온다.
					System.out.print(" | " + rs.getString("writer"));
					System.out.print(" | " + rs.getString("writeDate"));
					System.out.print(" | " + rs.getLong("hit"));
					System.out.println();
				} // end of while
				System.out.println("-------------------------------------------");
			} // end of if
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 7. 사용 리소스 닫기 - 오류가 나든 안나든 닫아야 한다. (try 밖에 선언 해야 한다.) (try-catch-finally 이용)
			// 사용 객체라 3개니까 3개를 닫아줘야 한다.
			try {
				// close() doc : void close() throws SQLException;
				// try catch를 강제하고 있어서 try 안에 넣어줘야 한다.
				// 닫는 순서는 상관 없지만 con->pstmt->rs 순서로 만들어지기 때문에 con 다음에 pstmt이 오류가 생길 수 있으므로
				// rs->pstmt->con 순서로 닫아주는게 좋다.
				// 아니면 아래처럼 if문장을 붙여주면 된다.
				// con != null -> con이 null이 아니면 -> con이 오류없이 실행 됐으면
				if (con != null)
					con.close();
				if (pstmt != null)
					pstmt.close();
				if (rs != null)
					rs.close();
				System.out.println("7. 닫기 성공");
			} catch (SQLException e) {
				// throw 시키면 Controller에서 잡게 한다.
				e.printStackTrace();
			} // end of try~catch of finally
		} // end of try~catch of main
	} // end of main
} // end of class


오류

  • 오류 코드
Connection con = DriverManager.getConnection("localhost", "java", "java");

  • 서버 위치 부분에 그냥 localhost 라고 적었더니 오류가 났다.
    jdbc:oracle:thin:@호스트이름:포트:SID 라고 적어주어야 오류가 나지 않는다.
  • 속성에서 확인해서 코드를 다시 작성해준다.
  • 다시 작성한 코드
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "java", "java");

Increase

package ch16jdbc;

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

public class IncreaseTestMain {

	public static void main(String[] args) {
		// 필요한 객체 선언
		Connection con = null;
		PreparedStatement pstmt = null;
		// rs는 필요하지 않다. update의 리턴 데이터는 int이다.
		
		try {
			// 1. 확인
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("1. 드라이버가 존재 합니다.");
			// 2. 접속
			con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","java","java");
			System.out.println("2. 접속이 잘 되었습니다.");
			// 3. sql - 변경되는 데이터는 물음표로 대체 해야 한다.
			String sql = "UPDATE board SET hit = hit + 1 WHERE no = ?";
			System.out.println("3. sql - " + sql);
			// 4. 실행 객체 & 데이터 세팅
			pstmt = con.prepareStatement(sql);
			pstmt.setLong(1, 2); // 1-> 첫번째 ?(물음표), 2-> 글번호, 나중에 no 변수로 세팅한다.
			System.out.println("4. 실행 객체 생성");
			// 5. 실행 - select - executeQuery. insert update, delete - executeUpdate()
			// 타입을 ResultSet 설정하면 맞는 타입인 executeQuery()메서드가 나온다.
			// ResultSet 타입을 쓰지 않기 때문에 rs 변수가 없어서 executeUpdate()메서드를 담을 변수를 하나 새로 만든다.
			int result = pstmt.executeUpdate();
			System.out.println("5. 실행 완료");
			// 6. 데이터표시
			System.out.println("6. 표시 - 조회수 1 증가 : " + result + "행이 수정되었습니다.");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 7. 닫기
				if (con != null) con.close();
				if (pstmt != null) pstmt.close();
				System.out.println("7. 닫기");
			} catch (Exception e) {
				e.printStackTrace();
			} // end of try~catch of finally 
		} // end of try~catch of main
	} // end of main
} // end of class

Increase 실행 후 List 변화

IncreaseTestMain class를 4번 실행해서 조회수가 4로 올라갔다.


View

package ch16jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
// import java.util.Scanner;

public class ViewTestMain {
	public static void main(String[] args) {
		// 필요한 객체 선언
//		Scanner scanner = new Scanner(System.in);
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		System.out.println("** 사용할 객체 선언 완료. **");
		
		try {
			// 1. 확인
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("1. 드라이버 확인");
			// 2. 연결
			con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","java","java");
			System.out.println("2. 접속 됨");
			// 3. sql
			String sql = "select no, title, content, writer, writeDate, hit from board where no = ?";
			System.out.println("3. sql - " + sql);
			// 4. 실행객체 & 데이터 세팅
			pstmt = con.prepareStatement(sql);
//			System.out.print("실행 할 글 번호 입력 --> ");
//			Long no = Long.parseLong(scanner.nextLine());
			pstmt.setLong(1, 4); // 현재는 그냥 2번글 가져오는걸로 세팅, 나중에는 변수 no로 세팅하면 됨.
			System.out.println("4. 실행 객체 완성");
			// 5. 실행 - rs : 한개의 데이터를 가져온다.
			rs = pstmt.executeQuery();
			System.out.println("5. 실행 완료.");
			// 6. 데이터 표시 - while 쓸 필요 없고 if문장 사용해서 next 써야한다.
			if (rs.next()) { // 데이터가 있는 경우만 출력하자.
				System.out.println("-------------------------------------------");
				System.out.println("- 번호 : " + rs.getLong("no"));
				System.out.println("- 제목 : " + rs.getString("title"));
				System.out.println("- 내용 : " + rs.getString("content"));
				System.out.println("- 작성자 : " + rs.getString("writer"));
				System.out.println("- 작성일 : " + rs.getString("writeDate"));
				System.out.println("- 조회수 : " + rs.getLong("hit"));
				System.out.println("-------------------------------------------");
			}
			System.out.println("6. 출력 완료");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 7. 닫기
				if (con != null)
					con.close();
				if (pstmt != null)
					pstmt.close();
				if (rs != null)
					rs.close();
				System.out.println("7. 닫기 성공");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

write

package ch16jdbc;

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

public class WriteTestMain {
	
	public static void main(String[] args) {	
		// BoardVO를 이용해서 데이터를 처리한다. 생성하고 데이터 넣기.
		BoardVO writeVo = new BoardVO();
		
		// 제목, 내용, 작성자, 비일번호 데이터 세팅한다.
		// scanner는 여기서 말고 controller에서 실행해 데이터 입력 받으면 된다.
		writeVo.setTitle("Java");
		writeVo.setContent("Java에서 생성한 게시판 내용");
		writeVo.setWriter("정다희");
		writeVo.setPw("1111");
		System.out.println("입력 할 데이터 작성 vo : " + writeVo);
		
		// 필요한 객체 선언
		Connection con = null;
		PreparedStatement pstmt = null;
		System.out.println("** 사용할 객체 선언 완료. **");
		
		try {
			
			// 1. 확인
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("1. 드라이버 확인");
			// 2. 연결
			con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","java","java");
			System.out.println("2. 접속 됨");
			// 3. sql
			String sql = " insert into board(no, title, content, writer, pw) " 
					+ " values(board_seq.nextval, ?, ?, ?, ?) "; // 두 줄로 나눌 경우 큰따움표 앞뒤로 띄어쓰기 넣기.
			System.out.println("3. sql - " + sql);
			// 4. 실행객체 & 데이터 세팅
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, writeVo.getTitle());
			pstmt.setString(2, writeVo.getContent());
			pstmt.setString(3, writeVo.getWriter());
			pstmt.setString(4, writeVo.getPw());
			System.out.println("4. 실행 객체 완성");
			// 5. 실행
			int result = pstmt.executeUpdate(); // insert, update, delete - executeUpdate();
			System.out.println("5. 실행 완료.");
			// 6. 표시
			if(result == 1) System.out.println("6. 등록 완료");
			else System.out.println("6. 등록 실패"); // insert인 경우 result == 1이 아니다 -> 오류
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 7. 닫기
				if (con != null)
					con.close();
				if (pstmt != null)
					pstmt.close();
				System.out.println("7. 닫기 성공");
			} catch (Exception e) {
				e.printStackTrace();
				
			}
		}
	}
}

update

package ch16jdbc;

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

public class UpdateTestMain {

	public static void main(String[] args) {
		// BoardVO에 수정할 데이터 세팅 - 번호, 제목, 내용, 작성자, 비밀번호
		BoardVO updateVo = new BoardVO();
		
		updateVo.setNo(2);
		updateVo.setTitle("제목수정");
		updateVo.setContent("내용수정");
		updateVo.setWriter("작성자수정");
		updateVo.setPw("1111");
		System.out.println("수정 데이터 vo : " + updateVo);
		
		Connection con = null;
		PreparedStatement pstmt = null;
		System.out.println("** 사용할 객체 선언 완료. **");
		
		try {
			// 1. 확인
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("1. 드라이버 확인");
			
			// 2. 연결
			con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","java","java");
			System.out.println("2. 연결 완료");
			
			// 3. sql
			String sql = "update board set title=?, content=?, writer=? where no=? and pw=?";
			System.out.println("3. sql - " + sql);
			
			// 4. 실행객체 & 데이터세팅
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, updateVo.getTitle());
			pstmt.setString(2, updateVo.getContent());
			pstmt.setString(3, updateVo.getWriter());
			pstmt.setLong(4, updateVo.getNo());
			pstmt.setString(5, updateVo.getPw());
			System.out.println("4. 실행 객체 + 데이터 세팅");
			
			// 5. 실행
			int result = pstmt.executeUpdate();
			System.out.println("5. 실행 완료.");
			
			// 6. 표시 - 비밀번호가 다르면 수정이 되면 안되기 때문에 if문을 쓴다.
			if(result == 1) System.out.println("6. 수정 완료");
			else System.out.println("6. 수정 실패"); // 비밀번호를 확인하세요.
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 7. 닫기
				if (con != null) con.close();
				if (pstmt != null) pstmt.close();
				System.out.println("7.닫기 성공");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

delete

package ch16jdbc;

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

public class DeleteTestMain {

	public static void main(String[] args) {
		
		// 삭제에 필요한 데이터 수집.
		// 컨트롤러에서 Scanner로 수집. 지금은 임의로 넣음.
		long no = 4;
		String pw = "1111";
		
		// BoardVO에 데이터 세팅
		BoardVO deleteVo = new BoardVO();
		deleteVo.setNo(no);
		deleteVo.setPw(pw);
		
		// 필요한 객체
		Connection con = null;
		PreparedStatement pstmt = null;
		System.out.println("필요한 객체 선언");
		
		try {
			// 1. 확인
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("1. 드라이버 확인");
			
			// 2. 연결
			con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","java","java");
			System.out.println("2. 연결 완료");
			
			// 3. sql
			String sql = "delete from board where no=? and pw=?";
			System.out.println("3. sql - " + sql);
			
			// 4. 실행객체 & 대이터 세팅
			pstmt = con.prepareStatement(sql);
			pstmt.setLong(1, deleteVo.getNo());
			pstmt.setString(2, deleteVo.getPw());
			System.out.println("4. 실행 객체 + 데이터 세팅");
			
			// 5. 실행
			int result = pstmt.executeUpdate();
			System.out.println("5. 실행 완료");
			
			// 6. 표시
			if(result == 1) System.out.println("6. 삭제 완료");
			else System.out.println("6. 삭제 실패");
					
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 7. 닫기
				if (con != null) con.close();
				if (pstmt != null) con.close();
				System.out.println("7. 닫기 성공");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

0개의 댓글