목차
- logging
- CRUD
- INSERT
- UPDATE
- DELETE
- JDBC 코딩 절차
6-1. Driver 등록
6-2. DBMS 연결
6-3. PreparedStatement 생성
6-4. SQL 전송 및 결과 반환
6-5. 자원 반환
1. logging
❗ DML(INSERT-UPDATE-DELETE) 활용에 앞서 로깅(logging) 처리를 진행한다. 콘솔창에서 입력 값이 어떻게 적용되어 출력으로 이어졌는지 보다 면밀히 확인할 수 있게 된다. 자세한 개념은 Spring Framework 단계에서 다루게 될 것이므로 당장은 활용을 위한 세팅 정도만 알아두자.
- 프로젝트 하위에 config 폴더 및 lib 폴더를 두고, 각각 해당 파일들을 배치한다.
- 프로젝트명 → 우클릭하여 Properties 클릭한다.
- Java Build Path → Source → Add Folder...로 접근해 저장해둔 config 폴더를 소스 폴더로 지정한다.
- Java Build Path → Libraries → Classpath에서 Add JARs...로 접근해 저장해둔 lib 폴더 하위 .jar 파일들을 반영한다.
✅ logging처리의 의미를 이해할 수 있다.
✅ logging처리를 위한 설정을 할 수 있다.
2. CRUD
CRUD | |
CREATE | INSERT |
READ | SELECT |
UPDATE | UPDATE |
DELETE | DELETE |
❗ int result = 0;
INSERT-UPDATE-DELETE는 삽입-수정-삭제한 행의 개수를 결과로 얻는다. ResultSet은 SELECT 결과 값을 받는 객체이다.
❗ result = pstmt.executeUpdate();
INSERT-UPDATE-DELETE 시에는 executeUpdate() 메소드로 실행한다. SELECT 시에는 executeQuery()를 사용한다.
3. INSERT
-- menu-query.xml
<entry key="insertMenu">
INSERT
INTO TBL_MENU A
(
A.MENU_CODE
, A.MENU_NAME
, A.MENU_PRICE
, A.CATEGORY_CODE
, A.ORDERABLE_STATUS
)
VALUES
(
SEQ_MENU_CODE.NEXTVAL
, ?
, ?
, ?
, ?
)
</entry>
- 시퀀스로 제작된 MENU_CODE 다음 번호를 불러온다: 시퀀스명.NEXTVAL
-- MenuDTO.class
private int code;
private String name;
.
.
- DTO 파일은 ① private 필드, ② 기본 생성자와 매개변수 있는 생성자, ③ 설정자(setter)와 접근자(getter), ④ 오버라이딩 된 toString() 메소드로 구성된다.
- 이때 필드값들은 테이블과 상응해야 한다: NUMBER 타입의 MENU_CODE → private int code;
-- Application.class
Scanner sc = new Scanner(System.in);
System.out.print("메뉴 이름을 입력하세요 : ");
String menuName = sc.nextLine();
System.out.print("메뉴 가격을 입력하세요 : ");
int menuPrice = sc.nextInt();
System.out.print("카테고리 코드를 입력하세요 : ");
int categoryCode = sc.nextInt();
System.out.print("판매 여부를 결정해 주세요(Y/N) : ");
sc.nextLine();
String orderableStatus = sc.nextLine().toUpperCase();
MenuDTO newMenu = new MenuDTO();
newMenu.setName(menuName);
newMenu.setPrice(menuPrice);
newMenu.setCategoryCode(categoryCode);
newMenu.setOrderableStatus(orderableStatus);
- 클래스를 따로 나누지 않은 채 입력 받는 상황을 가정한 예시이다.
- Scanner로부터 입력 받은 값들을 DTO에 뭉쳐 담아서 전송한다.
Connection con = getConnection();
PreparedStatement pstmt = null;
int result = 0;
Properties prop = new Properties();
- 사용할 객체들을 우선 선언한다.
- INSERT 실행을 통해 얻은 결과값은 행의 개수가 반환되므로 int형에 담는다.
try {
prop.loadFromXML(new FileInputStream("mapper/menu-query.xml"));
String query = prop.getProperty("insertMenu");
pstmt = con.prepareStatement(query);
pstmt.setString(1, newMenu.getName());
pstmt.setInt(2, newMenu.getPrice());
pstmt.setInt(3, newMenu.getCategoryCode());
pstmt.setString(4, newMenu.getOrderableStatus());
result = pstmt.executeUpdate();
- XML 파일로부터 쿼리문을 읽어온다.
- 위치홀더로 남겨두었던 값들을 세팅한다. 이때 인자로서 DTO 타입의 접근자(getter)를 활용한다.
- executeUpdate() 메소드로 실행한다.
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
close(con);
}
if(result > 0) {
System.out.println("메뉴 등록에 성공하였습니다.");
} else {
System.out.println("메뉴 등록에 실패하였습니다.");
}
- catch 구문을 통한 예외처리, finally 구문을 통한 close() 선언해야 한다.
- INSERT 쿼리문은 적용된 행의 개수를 결과로서 반납하기에, 사용자가 알아볼 수 있도록 if문을 통해 출력문 세팅한다.
✅ 변수의 값을 활용하여 insert 작업을 진행할 수 있다.
✅ DB에 저장할 값을 입력 받아 insert 작업을 진행할 수 있다.
✅ DTO 객체의 필드 값으로 insert 작업을 진행할 수 있다.
4. UPDATE
-- menu-query.xml
<entry key="updateMenu">
UPDATE
TBL_MENU A
SET A.MENU_NAME = ?
, A.MENU_PRICE = ?
WHERE A.MENU_CODE = ?
</entry>
-- Application.class
Scanner sc = new Scanner(System.in);
System.out.print("변경할 메뉴 번호를 입력하세요 : ");
int menuCode = sc.nextInt();
System.out.print("변경할 메뉴 이름을 입력하세요 : ");
sc.nextLine();
String menuName = sc.nextLine();
System.out.print("변경할 메뉴의 가격을 입력하세요 : ");
int menuPrice = sc.nextInt();
MenuDTO changedMenu = new MenuDTO();
changedMenu.setCode(menuCode);
changedMenu.setName(menuName);
changedMenu.setPrice(menuPrice);
- Scanner 통해 입력 받은 값들을 DTO 파일로 뭉쳐서 전달하도록 한다.
Connection con = getConnection();
PreparedStatement pstmt = null;
int result = 0;
Properties prop = new Properties();
- 사용할 객체들에 대해 우선 선언한다.
try {
prop.loadFromXML(new FileInputStream("mapper/menu-query.xml"));
String query = prop.getProperty("updateMenu");
pstmt = con.prepareStatement(query);
pstmt.setString(1, changedMenu.getName());
pstmt.setInt(2, changedMenu.getPrice());
pstmt.setInt(3, changedMenu.getCode());
result = pstmt.executeUpdate();
- XML 파일로부터 쿼리문을 읽어온다.
- 위치홀더로 남겨두었던 값들을 세팅한다. 이때 인자로서 DTO 타입의 접근자(getter)를 활용한다.
- executeUpdate() 메소드로 실행한다.
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
close(con);
if(result > 0) {
System.out.println("메뉴 변경에 성공하였습니다.");
} else {
System.out.println("메뉴 변경에 실패하였습니다.");
}
- catch 구문을 통한 예외처리, finally 구문을 통한 close() 선언해야 한다.
- UPDATE 쿼리문은 적용된 행의 개수를 결과로서 반납하기에, 사용자가 알아볼 수 있도록 if문을 통해 출력문 세팅한다.
✅ 변경할 값을 입력 받아 update 작업을 진행할 수 있다.
✅ DTO 객체의 필드 값으로 update 작업을 진행할 수 있다.
5. DELETE
-- menu-query.xml
<entry key="deleteMenu">
DELETE
FROM TBL_MENU A
WHERE A.MENU_CODE = ?
</entry>
-- Application.class
Scanner sc = new Scanner(System.in);
System.out.print("삭제할 메뉴 번호를 입력하세요 : ");
int menuCode = sc.nextInt();
Connection con = getConnection();
PreparedStatement pstmt = null;
int result = 0;
Properties prop = new Properties();
- Scanner 및 사용할 객체를 선언한다.
try {
prop.loadFromXML(new FileInputStream("mapper/menu-query.xml"));
String query = prop.getProperty("deleteMenu");
pstmt = con.prepareStatement(query);
pstmt.setInt(1, menuCode);
result = pstmt.executeUpdate();
- XML 파일로부터 쿼리문을 읽어오도록 한다.
- 위치홀더로 남겨두었던 값을 세팅한다.
- executeUpdate() 메소드로 실행한다.
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
close(con);
if(result > 0) {
System.out.println("선택 메뉴 삭제에 성공하였습니다.");
} else {
System.out.println("선택 메뉴 삭제에 실패하였습니다.");
}
- catch 구문을 통한 예외처리, finally 구문을 통한 close() 선언해야 한다.
- DELETE 쿼리문은 적용된 행의 개수를 결과로서 반납하기에, 사용자가 알아볼 수 있도록 if문을 통해 출력문 세팅한다.
✅ 입력 받은 값으로 DB의 행을 삭제할 수 있다.
6. JDBC 코딩 절차
6-1. Driver 등록
Class.forName("oracle.jdbc.driver.OracleDriver");
※ Class.forName(“com.Microsoft.jdbc.sqlserver. SQLServerDriver”);
※ Class.forName(“org.gjt.mm.mysql.Driver”);
- 이때 ojdbc8.jar 라이브러리에 대해 추가한다.
6-2. DBMS 연결
Connection con = DriverManager.getConnection("jdbc:log4jdbc:oracle:thin:@localhost:1521:xe", "user", "password");
- 별도 템플릿 클래스에 메소드로 만들어 활용할 수도 있다: public static Connection getConnection()
- 또는 인자로 (url, prop) 프로퍼티 파일을 전달할 수 있다. 어떤 DB에, 어떤 계정정보로 접속할지를 명시하는 것이다.
6-3. PreparedStatement 생성
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setXXX(순서, 값);
- SQL문 수행을 담당한다.
- 위치홀더 사용 시 순서에 맞춰 값 설정한다.
6-4. SQL 전송 및 결과 반환
String query = "SELECT * FROM EMPLOYEE";
ResultSet rset = pstmt.executeQuery(); -- SELECT일 때 실행 메소드
int result = pstmt.executeUpdate(); -- INSERT/UPDATE/DELETE일 때 실행 메소드
- rset.next() 커서를 옮겨가며 하나하나의 행을 참조한다.
- 상황에 따라 결과가 n개라면 while문, 1개라면 if문으로 작성한다.
- 해당 반복문/조건문 안에는 rset.getXXX("컬럼명")처럼 명시하여 관련 값을 불러오도록 한다.
6-5. 자원 반환
con.close();
또는 close(con);
- 사용 객체에 대하여 close() 선언해야 한다.
- 별도 템플릿 클래스 안에 객체별 close 메소드를 따로 정의해놓는 것도 방법이다.
'Database' 카테고리의 다른 글
[Oracle/2nd Review] Part 3. 오라클 객체 및 권한 (0) | 2022.02.04 |
---|---|
[JDBC] DAO | MVC 패턴 | CRUD | Query (0) | 2022.02.04 |
[JDBC] XML | SQL injection | PreparedStatement (0) | 2022.02.03 |
[Oracle/수업 과제 practice] DML (0) | 2022.01.30 |
[Oracle/수업 과제 practice] DDL(10~15번 문항) (0) | 2022.01.30 |