UpdateMemo
생성package kr.s04.preparedstatement;
import kr.s03.preparedstatement.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class UpdateMemo {
public static void main(String[] args) {
BufferedReader br = null;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("메모를 수정합니다.");
System.out.print("메모 번호 > ");
int num = Integer.parseInt(br.readLine());
System.out.print("제목 > ");
String title = br.readLine();
System.out.print("작성자 > ");
String name = br.readLine();
System.out.print("내용 > ");
String memo = br.readLine();
System.out.print("이메일 > ");
String email = br.readLine();
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// 빈 행을 입력받은 경우, 기존 정보를 유지할 수 있게끔 SELECT문 실행
if(title.equals("")|name.equals("")|memo.equals("")|email.equals("")) {
sql = "SELECT * FROM test2 WHERE num=?";
PreparedStatement pstmt2 = conn.prepareStatement(sql);
pstmt2.setInt(1, num);
rs = pstmt2.executeQuery();
if(rs.next()) {
if (title.equals("")) title = rs.getString("title");
if (name.equals("")) name = rs.getString("name");
if (memo.equals("")) memo = rs.getString("memo");
if (email.equals("")) email = rs.getString("email");
}
DBUtil.executeClose(rs, pstmt2, null); // 자원 정리를 하기 위해서는 SQL문장마다 별도의 PreparedStatement 객체를 생성해야 함
}
// SQL문 작성
sql = "UPDATE test2 SET title=?, name=?, memo=?, email=? WHERE num=?";
// JDBC 수행 3단계
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setString(1, title);
pstmt.setString(2, name);
pstmt.setString(3, memo);
pstmt.setString(4, email);
pstmt.setInt(5, num);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블의 행 변경
int count = pstmt.executeUpdate();
System.out.println(count + "개 행의 정보를 수정했습니다.");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(null, pstmt, conn);
if(br!=null) try {br.close();} catch(Exception e) {}
}
}
}
DeleteMemo
생성package kr.s04.preparedstatement;
import kr.s03.preparedstatement.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class DeleteMemo {
public static void main(String[] args) {
BufferedReader br = null;
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("메모를 삭제합니다.");
System.out.print("메모 번호 > ");
int num = Integer.parseInt(br.readLine());
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// SQL문 작성
sql = "DELETE FROM test2 WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setInt(1, num);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블의 행을 삭제
int count = pstmt.executeUpdate();
System.out.println(count + "개 행이 삭제되었습니다.");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
if(br!=null) try {br.close();} catch(Exception e) {}
DBUtil.executeClose(null, pstmt, conn);
}
}
}
java.sql
패키지에 포함된 인터페이스로, PreparedStatement를 상속받음{[? = ]call 프로시저명 [(?, ?, ...)]}
registerOutparameter()
메서드로 등록되어 있어야 함kr.s05.callablestatement
생성하고 table.sql
생성CREATE TABLE salary(
name VARCHAR2(30) PRIMARY KEY,
pay NUMBER
);
INSERT INTO salary VALUES('TEST', 1000);
INSERT INTO salary VALUES('CALL', 2000);
INSERT INTO salary VALUES('PROCEDURE', 3000);
COMMIT;
CREATE OR REPLACE PROCEDURE adjust(name_i IN VARCHAR2, rate IN FLOAT)
AS
newpay FLOAT;
BEGIN
SELECT pay INTO newpay FROM salary WHERE name = name_i;
newpay := newpay * (1 + rate);
UPDATE salary SET pay=newpay WHERE name = name_i;
COMMIT;
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(name_i || ' 갱신 실패');
ROLLBACK;
END;
kr.s03.preparedstatement
패키지의 DBUtil
클래스에 executeClose()
메서드 오버로딩을 추가package kr.s03.preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
private static final String DB_DRIVER = "oracle.jdbc.OracleDriver";
private static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:xe";
private static final String DB_ID = "scott";
private static final String DB_PASSWORD = "tiger";
// Connection 객체 생성 및 반환
public static Connection getConnection() throws ClassNotFoundException, SQLException {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(DB_DRIVER);
// JDBC 수행 2단계 : Connection 객체 생성
return DriverManager.getConnection(DB_URL, DB_ID, DB_PASSWORD);
}
// 자원 정리
public static void executeClose(ResultSet rs, PreparedStatement pstmt, Connection conn) {
if(rs!=null) try {rs.close();} catch(SQLException e) {}
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
public static void executeClose(CallableStatement cstmt, Connection conn) {
if(cstmt!=null) try {cstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
}
CallableStatementMain
생성package kr.s05.callablestatement;
import kr.s03.preparedstatement.DBUtil;
import java.sql.CallableStatement;
import java.sql.Connection;
public class CallableStatementMain {
public static void main(String[] args) {
Connection conn = null;
CallableStatement cstmt = null;
String sql = null;
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// 프로시저 호출 문장 작성
sql = "{call adjust(?, ?)}"; // 인자에 직접 값을 입력하지 않고 바인드 변수 ? 사용
// JDBC 수행 3단계 : CallableStatement 객체 생성
cstmt = conn.prepareCall(sql);
// ?에 데이터를 바인딩
cstmt.setString(1, "CALL");
cstmt.setFloat(2, 0.06f);
// JDBC 수행 단계 : 프로시저 실행
cstmt.executeUpdate();
System.out.println("급여 정보가 수정되었습니다.");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(cstmt, conn);
}
}
}
java.sql
패키지에 포함된 인터페이스setAutoCommit()
true
혹은 false
로 설정하는 메서드
true
이며, 개별 SQL문이 개별 트랜잭션으로서 실행 및 COMMIT됨false
로 설정commit()
false
인 경우에만 사용rollback()
false
인 경우에만 사용kr.s06.transaction
생성하고 새 클래스 TransactionMain
생성package kr.s06.transaction;
import kr.s03.preparedstatement.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TransactionMain {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
PreparedStatement pstmt3 = null;
String sql = null;
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// 트랜잭션 처리를 위해서 자동 COMMIT 해제
conn.setAutoCommit(false);
// SQL문 작성
sql = "INSERT INTO test1 VALUES (?, ?)";
// JDBC 수행 3단계;
pstmt1 = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt1.setString(1, "test");
pstmt1.setInt(2, 10);
// JDBC 수행 4단계 : SQL문 실행
pstmt1.executeUpdate();
sql = "INSERT INTO test1 VALUES (?, ?)";
pstmt2 = conn.prepareStatement(sql);
pstmt2.setString(1, "COMMIT");
pstmt2.setInt(2, 20);
pstmt2.executeUpdate();
// 트랜잭션 테스트를 위해 오류가 있는 SQL문 작성
sql = "INSERT INTO test1 VALUES (?, ?";
pstmt3 = conn.prepareStatement(sql);
pstmt3.setString(1, "ROLLBACK");
pstmt3.setInt(2, 30);
pstmt3.executeUpdate();
// 모든 SQL문이 정상적으로 처리되면 COMMIT
conn.commit();
System.out.println("작업 완료");
}
catch(Exception e) {
e.printStackTrace();
// 예외 발생하면 ROLLBACK
try {
conn.rollback();
}
catch(SQLException se) {
se.printStackTrace();
}
}
finally {
DBUtil.executeClose(null, pstmt1, null);
DBUtil.executeClose(null, pstmt3, null);
DBUtil.executeClose(null, pstmt2, conn); // PreparedStatement 객체가 여러 개일 때, 각각의 정리 순서는 중요하지 않고 Connection 객체만 마지막에 정리하면 됨
}
}
}
kr.s07.note
생성하고 table.sql
생성CREATE TABLE note(
num NUMBER PRIMARY KEY,
name VARCHAR2(30) NOT NULL,
passwd VARCHAR2(10) NOT NULL,
subject VARCHAR2(60) NOT NULL,
content VARCHAR2(4000) NOT NULL,
email VARCHAR2(60),
reg_date DATE NOT NULL
);
CREATE SEQUENCE note_seq;
NoteMain
생성package kr.s07.note;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class NoteMain {
private BufferedReader br;
private NoteDAO note; // callMenu() 메서드에서 사용하기 때문에 멤버 변수로 선언
public NoteMain() {
note = new NoteDAO();
try {
br = new BufferedReader(new InputStreamReader(System.in));
callMenu();
}
catch(IOException e) {
e.printStackTrace();
}
finally {
if(br!=null) try {br.close();} catch(IOException e) {}
}
}
// 메뉴
public void callMenu() throws IOException {
while(true) {
System.out.println("메뉴 : 1. 글 쓰기, 2. 목록 보기, 3. 상세 글 보기, 4. 글 수정, 5. 글 삭제, 6.종료");
System.out.print("메뉴 > ");
try {
int menu = Integer.parseInt(br.readLine());
if(menu==1) { // 글 쓰기
System.out.print("이름 > ");
String name = br.readLine();
System.out.print("비밀번호 > ");
String passwd = br.readLine();
System.out.print("제목 > ");
String subject = br.readLine();
System.out.print("내용 > ");
String content = br.readLine();
System.out.print("이메일 > ");
String email = br.readLine();
// NoteDAO의 insertInfo() 메서드를 호출해서 데이터를 전달
note.insertInfo(name, passwd, subject, content, email);
}
else if(menu==2) { // 목록 보기
note.selectListInfo();
}
else if(menu==3) { // 상세 글 보기
note.selectListInfo(); // 글 번호 확인용 목록 보기
System.out.println("상세 정보를 확인하려는 글 번호를 입력하세요!");
System.out.print("글 번호 > ");
int num = Integer.parseInt(br.readLine());
note.selectDetailInfo(num);
}
else if(menu==4) { // 글 수정
note.selectListInfo(); // 글 번호 확인용 목록 보기
System.out.println("수정하려는 글 번호를 입력하세요!");
int num;
while(true) { // 올바른 글 번호 입력 강제
System.out.print("글 번호 > ");
num = Integer.parseInt(br.readLine());
if(note.selectDetailInfo(num)==1) break;
}
System.out.println("수정할 내용을 입력하세요!");
System.out.print("이름 > ");
String name = br.readLine();
System.out.print("비밀번호 > ");
String passwd = br.readLine();
System.out.print("제목 > ");
String subject = br.readLine();
System.out.print("내용 > ");
String content = br.readLine();
System.out.print("이메일 > ");
String email = br.readLine();
note.updateInfo(num, name, passwd, subject, content, email);
}
else if(menu==5) { // 글 삭제
note.selectListInfo(); // 글 번호 확인용 목록 보기
System.out.println("삭제하려는 글 번호를 입력하세요!");
System.out.print("글 번호 > ");
int num = Integer.parseInt(br.readLine());
note.deleteInfo(num);
note.selectListInfo(); // 삭제가 정상적으로 수행되었는지 확인하기 위해 목록 호출
}
else if(menu==6) { // 종료
System.out.println("프로그램을 종료합니다.");
break;
}
else {
System.out.println("잘못 입력했습니다!");
}
}
catch(NumberFormatException e) {
System.out.println("숫자만 입력 가능합니다!");
}
}
}
public static void main(String[] args) {
new NoteMain();
}
}
NoteDAO
생성package kr.s07.note;
import kr.s03.preparedstatement.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/*
* DAO(Data Access Object): 데이터베이스의 데이터를 전문적으로 호출하고 제어하는 객체
*/
public class NoteDAO {
// 글 쓰기
public void insertInfo(String name, String passwd, String subject, String content, String email) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// SQL문 작성
sql = "INSERT INTO note VALUES (note_seq.NEXTVAL, ?, ?, ?, ?, ?, SYSDATE)";
// JDBC 수행 3단계 : PreparedStatment 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setString(1, name);
pstmt.setString(2, passwd);
pstmt.setString(3, subject);
pstmt.setString(4, content);
pstmt.setString(5, email);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블에 행을 추가
int count = pstmt.executeUpdate();
if(count==1) System.out.println("글 작성이 완료되었습니다.");
else System.out.println("글 작성에 실패하였습니다.");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(null, pstmt, conn);
}
}
// 목록 보기
public void selectListInfo() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// SQL문 작성
sql = "SELECT * FROM note ORDER BY num DESC";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블로부터 결과 집합을 얻고 ResultSet에 담아서 반환
rs = pstmt.executeQuery();
System.out.println("글 번호\t제목\t\t이름\t작성일");
String subject, name;
while(rs.next()) {
System.out.print(rs.getInt("num")+"\t");
subject = rs.getString("subject");
if(subject.length()>6+6) { // 제목이 길면 말줄임표 처리; 길이 상한이 60byte(=국문 20자)이므로, 정렬용으로 \t 2개 사용
System.out.print(subject.substring(0,4+6)+"..\t");
}
else if(subject.length()>7) {
System.out.print(subject+"\t");
}
else {
System.out.print(subject+"\t\t");
}
name = rs.getString("name");
if(name.length()>6) { // 이름이 길면 말줄임표 처리
System.out.print(name.substring(0,4)+"..\t");
}
else {
System.out.print(name+"\t");
}
System.out.println(rs.getDate("reg_date")); // 목록 보기에서는 연, 월, 일만 표시
}
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(rs, pstmt, conn);
}
}
// 상세 글 보기
public int selectDetailInfo(int num) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs= null;
String sql = null;
int exitcode = 0; // if~else 도달 전에 예외 발생할 수 있으므로 기본값 지정
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// SQL문 작성
sql = "SELECT * FROM note WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setInt(1, num);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블로부터 한 개의 레코드를 얻고 ResultSet에 담아서 반환
rs = pstmt.executeQuery();
if(rs.next()) {
System.out.println("글 번호 : " + rs.getInt("num"));
System.out.println("이름 : " + rs.getString("name"));
System.out.println("비밀번호 : " + rs.getString("passwd"));
System.out.println("제목 : " + rs.getString("subject"));
System.out.println("내용 : " + rs.getString("content"));
System.out.println("이메일 : " + rs.getString("email"));
System.out.println("작성일 : " + rs.getString("reg_date")); // 상세 글 보기에서는 연, 월, 일, 시, 분, 초까지 표시
exitcode = 1; // 있는 글 번호를 입력하여 정상적으로 상세 글 보기 작업을 완료한 경우
}
else {
System.out.println(num + "번 글이 존재하지 않습니다!");
exitcode = -1; // 없는 글 번호를 입력하여 상세 글 보기 작업에 실패한 경우
}
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(rs, pstmt, conn);
}
return exitcode;
}
// 글 수정
public void updateInfo(int num, String name, String passwd, String subject, String content, String email) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// 빈 문자열을 입력받은 경우 기존 정보를 유지하기
if((name+passwd+subject+content+email).equals("")) {
System.out.println("수정할 내용이 없습니다!");
return;
}
if(name.equals("")|passwd.equals("")|subject.equals("")|content.equals("")|email.equals("")) {
sql = "SELECT * FROM note WHERE num=?";
PreparedStatement pstmt2 = conn.prepareStatement(sql);
pstmt2.setInt(1, num);
ResultSet rs = pstmt2.executeQuery();
if(rs.next()) {
if (name.equals("")) name = rs.getString("name");
if (passwd.equals("")) passwd = rs.getString("passwd");
if (subject.equals("")) subject = rs.getString("subject");
if (content.equals("")) content = rs.getString("content");
if (email.equals("")) email = rs.getString("email");
}
DBUtil.executeClose(rs, pstmt2, null);
}
// SQL문 작성
sql = "UPDATE note SET name=?, passwd=?, subject=?, content=?, email=? WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setString(1, name);
pstmt.setString(2, passwd);
pstmt.setString(3, subject);
pstmt.setString(4, content);
pstmt.setString(5, email);
pstmt.setInt(6, num);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블의 행 정보 갱신
int count = pstmt.executeUpdate();
if(count==1) System.out.println(num + "번 글을 수정하였습니다.");
else System.out.println(num + "번 글을 수정하지 못했습니다!");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(null, pstmt, conn);
}
}
// 글 삭제
public void deleteInfo(int num) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
// JDBC 수행 1,2단계
conn = DBUtil.getConnection();
// SQL문 작성
sql = "DELETE FROM note WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setInt(1, num);
// JDBC 수행 4단계 : SQL문을 실행해서 테이블의 행을 삭제
int count = pstmt.executeUpdate();
if(count==1) System.out.println(num + "번 글을 삭제하였습니다.");
else System.out.println(num + "번 글을 삭제하지 못했습니다!");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
DBUtil.executeClose(null, pstmt, conn);
}
}
}