1. PreparedStatement (준비된 Statement) 정리
- '미리' SQL문이 셋팅된 Statement가 DB에 전송되어져서 컴파일되어지고, SQL문의 '?'만 나중에 추가 셋팅하여 실행되는 '준비된 Statement'.
2. 장점
(1) Statement 에 비해서 반복적인 SQL문을 사용할 경우에 더 빠르다.(특히, 검색)
(2) DB컬럼타입과 상관없이 ? 하나로 표시하면 됨. 개발자가 헷깔리지 않고 쉽다. (특히, INSERT문)
(이유: ? 를 제외한 SQL문이 DB에서 미리 컴파일되어져서 대기)
3. 단점
SQL문마다 PreparedStatement 객체를 각각 생성해야 하므로 재사용불가.
(but, Statement 객체는 SQL문이 달라지더라도 한 개만 생성해서 재사용이 가능함.)
4. 특징
(1) Statement stmt = con.createStatement(); //생성
stmt.execute(sql);//실행
(2) PreparedStatement pstmt = con.prepareStatement(sql); //생성
pstmt.execute(); //실행
import java.sql.*;
class A {
Connection con;
String url = "jdbc:oracle:thin:@61.81.98.62:1521:JAVA"; // localhost or 127.0.0.1
Statement stmt;
PreparedStatement pstmtIn;
PreparedStatement pstmtUp;
PreparedStatement pstmtDel;
PreparedStatement pstmtSelNo;
PreparedStatement pstmtSelName;
String sqlIn = "insert into JDBCT values(?, ?, ?)" ;
String sqlUp = "update JDBCT set NAME=?, ADDR=? where NO=?";
String sqlDel = "delete from JDBCT where NO=?";
String sqlSelNo = "select * from JDBCT where NO=?";
String sqlSelName = "select * from JDBCT where NAME like ?";
ResultSet rs;
ResultSetMetaData rsmd;
A() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(url, "scott", "tiger");
stmt = con.createStatement();
pstmtIn = con.prepareStatement(sqlIn);
pstmtUp = con.prepareStatement(sqlUp);
pstmtDel = con.prepareStatement(sqlDel);
pstmtSelNo = con.prepareStatement(sqlSelNo);
pstmtSelName = con.prepareStatement(sqlSelName);
} catch(ClassNotFoundException cnfe) {
pln("오라클 드라이버 로딩 실패(예외): " + cnfe);
} catch(SQLException se) {
pln("오라클과 연결 실패 or Statement 생성 실패(예외): " + se);
}
}
void insert(int no, String name, String addr) {
try {
pstmtIn.setInt(1, no);
pstmtIn.setString(2, name);
pstmtIn.setString(3, addr);
int i = pstmtIn.executeUpdate();
if(i > 0) {
pln("입력 성공");
con.commit();
}
else pln("입력 실패");
} catch(SQLException se) {
pln("입력실패(예외): " + se);
}
}
void update(String name, String addr, int no) {
try {
pstmtUp.setString(1, name);
pstmtUp.setString(2, addr);
pstmtUp.setInt(3, no);
int i = pstmtUp.executeUpdate();
if(i > 0) {
pln("수정 성공");
con.commit();
}
else pln("수정 실패");
} catch(SQLException se) {
pln("수정실패(예외): " + se);
}
}
void delete(int no){
try{
pstmtDel.setInt(1, no);
int i = pstmtDel.executeUpdate();
if(i > 0) {
pln("삭제 성공");
con.commit();
}
else pln("삭제 실패");
} catch(SQLException se){
pln(se.getSQLState());
}
}
void select() {
try {
String sql = "select * from jdbct order by NO";
rs = stmt.executeQuery(sql);
rsmd = rs.getMetaData();
int colCnt = rsmd.getColumnCount();
for(int i=1; i<=colCnt; i++) {
String colName = rsmd.getColumnName(i);
p(colName+"\t");
}
pln("\n-------------------------");
while(rs.next()) {
int no = rs.getInt(1);
String name = rs.getString(2);
String addr = rs.getString(3);
pln(no + "\t" + name + "\t" + addr);
}
} catch(SQLException se){
pln("검색 실패(예외): " + se);
}
}
void select(int n) {
try {
pstmtSelNo.setInt(1, n);
rs = pstmtSelNo.executeQuery();
rsmd = rs.getMetaData();
int colCnt = rsmd.getColumnCount();
for(int i=1; i<=colCnt; i++) {
String colName = rsmd.getColumnName(i);
p(colName+"\t");
}
pln("\n-------------------------");
while(rs.next()) {
int no = rs.getInt(1);
String name = rs.getString(2);
String addr = rs.getString(3);
pln(no + "\t" + name + "\t" + addr);
}
} catch(SQLException se){
pln("검색 실패(예외): " + se);
}
}
void select(String str) {
try {
pstmtSelName.setString(1, str+"%");
rs = pstmtSelName.executeQuery();
rsmd = rs.getMetaData();
int colCnt = rsmd.getColumnCount();
for(int i=1; i<=colCnt; i++) {
String colName = rsmd.getColumnName(i);
p(colName+"\t");
}
pln("\n-------------------------");
while(rs.next()) {
int no = rs.getInt(1);
String name = rs.getString(2);
String addr = rs.getString(3);
pln(no + "\t" + name + "\t" + addr);
}
} catch(SQLException se){
pln("검색 실패(예외): " + se);
}
}
void closeAll() {
try {
if(rs != null) rs.close();
if(pstmtIn != null) pstmtIn.close();
if(pstmtUp != null) pstmtUp.close();
if(pstmtDel != null) pstmtDel.close();
if(pstmtSelNo != null) pstmtSelNo.close();
if(pstmtSelName != null) pstmtSelName.close();
if(stmt != null) stmt.close();
if(con != null) con.close();
} catch(SQLException se) {}
}
void p(String str) {
System.out.print(str);
}
void pln(String str) {
System.out.println(str);
}
public static void main(String[] args) {
A a = new A();
a.insert(10, "홍길동", "서울시");
a.insert(20, "강감찬", "부산시");
a.insert(30, "김철수", "대전시");
a.delete(30);
a.update(10, "이철민", "평양시");
a.select();
a.closeAll();
}
}
5. 주의
- DB 객체들(table, ..)의 뼈대(테이블명 or 컬럼명 or 시퀀스명 등의 객체나 속성명은 '?' 로 표시할 수 없다.
즉, data 자리에만 ?로 표시할 수 있다.
cf) 그래서, DDL문에서는 PreparedStatement를 사용하지 않는다.
6. CallableStatement (호출할 수 있는 Statement) 정리
(1) 설명
- DataBase 에 미리 컴파일되어 있는 Stored Procedure를 호출하기 위한 Statement.
(2) 생성 / 호출
- String sql = "{call incre(?,?)}";
CallableStatement cstmt = con.prepareCall(sql);
import java.sql.*;
class B {
String sql = "{call incre(?, ?)}";
String url = "jdbc:oracle:thin:@61.81.98.62:1521:JAVA";
Connection con;
CallableStatement cstmt;
B() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(url, "scott", "tiger");
cstmt = con.prepareCall(sqlCall);
callP(7369, 0.5f);
closeAll();
} catch(ClassNotFoundException cnfe) {
pln("오라클 드라이버 로딩 실패(예외): " + cnfe);
} catch(SQLException se) {
pln("오라클과 연결 실패 or Statement 생성 실패(예외): " + se);
}
}
void callP(int i, float f) {
try {
cstmt.setInt(1, i);
cstmt.setFloat(2, f);
cstmt.execute();
pln("급여인상완료");
} catch(SQLException se) {}
}
void closeAll() {
try {
if(cstmt != null) cstmt.close();
if(con != null) con.close();
} catch(SQLException se) {}
}
void p(String str) {
System.out.print(str);
}
void pln(String str) {
System.out.println(str);
}
public static void main(String[] args) {
new B();
}
}
'개발 > JAVA' 카테고리의 다른 글
[annotation] @Autowired와 @Qualifier (0) | 2024.04.24 |
---|---|
25. JAVA JDBC (Java Database Connectivity) - 3 (0) | 2020.06.08 |
23. JAVA JDBC (Java Database Connectivity) - 1 (0) | 2020.06.08 |
22. JAVA Network 네트워크 (0) | 2020.06.08 |
21. JAVA IO (Input / Output) / 파일 입출력 스트림 / 파일 (File) 클래스 (0) | 2020.06.08 |