21.02.05
[DataBase - Statement]
<%
//1. DB접속
//1-1. context.xml을 객체화 해서 가져온다.
Context ctx = new InitialContext();
//1-2. name을 통해서 해당 Resource를 찾아 DataSource로 변환해준다.
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle");
//1-3. DataSource를 통해 Connection을 가져온다.
Connection conn = ds.getConnection();
if(conn != null){
out.println("<h2>연결완료</h2>");
}
//2. 쿼리실행
//2-1. 쿼리문 준비
String sql = "CREATE TABLE member("
+"id VARCHAR2(50),"
+"pw VARCHAR2(200),"
+"name VARCHAR2(50),"
+"age NUMBER(4),"
+"gender VARCHAR2(4),"
+"email VARCHAR2(100),"
+"reg_date DATE DEFAULT SYSDATE"
+")";
//2-2. Statement 준비
Statement stmt = conn.createStatement();
//3.쿼리문 실행
int cnt = stmt.executeUpdate(sql);
System.out.println("cnt:" +cnt); //테이블 생성은 데이터와 관련된 것이 아니므로 0반환
out.print("<h3>테이블생성완료</h3>");
//3. 자원반납
conn.close();
%>
- 한번 실행 후 다시 실행되지 않는다면 Statement가 낫다.
- 순서
1. DB접속
1-1) context.xml 객체화
1-2) name을 이용해서 Resource를 찾아 DataSource로 변환
1-3) DataSource를 통해 Connection을 가져온다.
2. 쿼리실행
2-1) 쿼리문 준비
2-2) Connection을 이용해 Statement준비
- connction.crateStatement()
2-3) 쿼리문 실행
- executeUpdate() : DB에 변화를 줄 경우 사용한다.(UPDATE,DELETE,INSERT)
- executeUpdate() 사용시 반환되는 int는 적용에 성공한 데이터 개수이다.
- 위내용으로는 테이블 생성은 데이터와 관련된 것이 아니므로 0반환된다.
3. 자원반납
[DataBase - PreparedStatement]
<%
//1.DB접속
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle");
Connection conn = ds.getConnection();
System.out.println(conn);
//2. 쿼리실행
//2-1. 쿼리문준비
String sql = "INSERT INTO member(id,pw,name,age,gender,email) VALUES(?,?,?,?,?,?)";
//2-2. Connection으로 부터 PreparedStatement 가져오기
PreparedStatement pstmt = conn.prepareStatement(sql);
//pstmt는 각?에 무엇이 들어가는지 알려줘야한다.
for(int i=1;i<=5;i++){
pstmt.setString(1, "admin"+i);//첫번째 물음표에 admin 삽입
pstmt.setString(2, "pass"+i);
pstmt.setString(3, "user"+i);
pstmt.setInt(4, 20+i);
pstmt.setString(5, "남");
pstmt.setString(6, "[email protected]");
//2-3. 쿼리 실행(executeQuery,executeUpdate)
if(pstmt.executeUpdate()!=0){
out.println("<h3>"+i+"번째 데이터 입력완료</h3>");
}
}
//3. 자원반납
conn.close();
%>
- Statement 보다 PreparedStatement 훨씬 많이 사용한다.
- 문장을 컴파일 한 후 재사용한다.
- 그래서 문장이 여러번 반복 될 때 유리하며 성능과 속도 면에서 유리하다.
- 순서
1. DB접속
1-1) Context.xml 객체화
1-2) name으로 Resource를 찾아 DataSource로 변환
1-3) DataSource를 이용해 Connection 가져오기
2. 쿼리실행
2-1) 쿼리문준비
2-2) Connection으로 부터 PreparedStatement 가져오기
2-3) 각 ?에 값 넣어주기
2-4) 쿼리 실행
3. 자원반납
[DataBase - ResultSet]
<%
//1. DB접속
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle");
Connection conn = ds.getConnection();
//2. 쿼리실행
//2-1. 쿼리문 준비
String sql = "SELECT * FROM member";
//2-2. Connection으로 부터 PreparedStatement가져오기
PreparedStatement pstmt = conn.prepareStatement(sql);
//2-3. ?대응 - 이번 쿼리는 ?가 없으므로 사용안함
//2-4. 쿼리 실행
ResultSet rs= pstmt.executeQuery();
System.out.println(rs);
//다음값이 있으면 T 없으면 F
while(rs.next()){//다음값이 있나?
out.print("<p>"
+rs.getString(1)+" | "
+rs.getString("pw")+" | "
+rs.getInt("age")+" | "
+rs.getString("gender")+" | "
+rs.getString("email")+" | "
+rs.getDate("reg_date")
+"</p>");
}
//ResultSet에서 metadata를 뽑을 수 있다.
ResultSetMetaData meta = rs.getMetaData();
/*desc명령어와 유사하다.*/
out.println("<p>컬럼수:"+meta.getColumnCount()+"</p>");
//컬럼의 이름과 타입, 사이즈
for(int i=1;i<=meta.getColumnCount();i++){
out.println(meta.getColumnName(i)
+" "+meta.getColumnTypeName(i)+"("+meta.getColumnDisplaySize(i)
+")"+"</br>");
}
//3. 자원반납
rs.close();
conn.close();
%>
- executeQurey() 는 값을 조회하는 쿼리를 실행 해 주는 메서드 이다.
- 때문에 결과값을 ResultSet 객체로 반환한다.
- ResultSet에서 metadata를 뽑을 수 있다.
- 순서
1. DB접속
2. 쿼리실행
2-1) 쿼리문준비
2-2) Connection으로 부터 PreparedStatement 가져오기
2-3) ?대응 - 이번 쿼리는 ?가 없으므로 사용안함
2-4) 쿼리 실행
- next() 다음행으로 커서 이동(데이터 존재 여부를 boolean 으로 반환)
- executeQuery() : 반환되는 데이터가 있을경우 사용한다.(SELECT)
- getTYPE(컬럼인덱스지정) : 해당데이터를 지정한 타입으로 가져온다.
- getTYPE(컬럼명지정) : 해당데이터를 지정한 타입으로 가져온다.
[Data Base – Transaction]
<%
//1.DB접속
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle");
Connection conn = ds.getConnection();
conn.setAutoCommit(false);//트랙젝션 수동 설정
try{
//2.쿼리실행(쿼리1 : 정상, 쿼리2 : 비정상)
String sql1 = "INSERT INTO member(id,pw,name,age,gender,email)
VALUES('tranx2','pass','관리자','40','남','[email protected]')";
PreparedStatement ps = conn.prepareStatement(sql1);
int success = ps.executeUpdate();
System.out.println("success1 : " + success);
ps.close();
//실패가 났을 경우 ..sql1의 쿼리 실행도 취소가 되는가?
String sql2 = "INSERT INTO member2(id,pw,name,age,gender,email)
VALUES('tranx2','pass','관리자','40','남','[email protected]')";
ps = conn.prepareStatement(sql2);
success = ps.executeUpdate();
System.out.println("success2 : " + success);
conn.commit();
out.println("<h3>커밋하겠습니다.</h3>");
ps.close();
}catch(Exception e){
e.printStackTrace();// 개발자만 확인할수 있도록 처리
conn.rollback();
out.println("<h3>쿼리 실행중 문제가 발생하여 롤백 하였습니다.</h3>");
}finally{
conn.close();
}
%>
- transaction : DB에서 사용되는 쪼갤 수 없는 업무처리의 단위이다.(ex.인터넷뱅킹)
- 트랜젝션 수동 설정을 안해줬을 경우에 비정상쿼리가 있더라도 정상쿼리는 DB랑 연결되어
데이터가 들어가게 된다.
- 그래서 트랜젝션 수동 설정을 해줘야한다.
- try-catch문을 만들어 예외발생시 rollback()하게 한다.
Author And Source
이 문제에 관하여(21.02.05), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@mingmang17/21.02.05저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)