JDBC - DML_INSERT

kxsxh·2024년 3월 7일
0

JDBC

목록 보기
1/3

Java Database Connectivity

: 자바 기반 애플리케이션의 데이터를 데이터베이스에 저장 및 업데이트하거나, 데이터베이스에 저장된 데이터를 JAVA에서 사용할 수 있도록 하는 JAVA API이다

Connection conn = null;

Connection conn : 데이터베이스 서버와 연결을 맺어주는 자바의 객체이자 오라클 데이터베이스 서버이다

PreparedStatement pstmt = null; : Connection conn(연결한 DB서버)에 전송할 SQL문(편지)을 전송(전달)을 해주는 객체(우편배달부)이다
--> `PreparedStatement pstmt' 객체는 (우편배달부)는 작성된 sql문(편지)을 오라클 서버에 보내서 실행이 되도록 해주는 객체이다

pstmt: 매개변수화된 SQL 쿼리를 실행하기 위한 'PreparedStatement' 개체이자 이것을 사용하면 동일한 쿼리를 여러 번 실행하더라도 데이터베이스에서 쿼리를 한 번 컴파일하고 최적화할 수 있으므로 성능이 향상된다 또한 보안상의 이점도 있다

쿼리 : 데이터베이스로부터 정보를 요청하는 것

매개변수화된 sql 쿼리 : 쿼리에 사용자로부터 입력 받은 값을 직접 삽입하는 대신에, 쿼리 안에 특정한 위치에 플레이스 홀더(대개는 물음표 '?'로 표시됨)를 두고, 이 플레이스홀더를 실제 값으로 대체하여 실행하는 쿼리 방법을 말합니다
즉, 쿼리를 작성할 때 직접 넣는 대신에, 값을 나중에 전달할 수 있도록 공간을 확보하는 것이다


1. 오라클 드라이버 로딩

OracleDriver(오라클 드라이버)의 역할

1) OracleDriver를 메모리에 로딩시켜준다
2) OracleDriver 객체를 생성해준다
3) OracleDriver 객체를 DriverManager에 등록시켜준다
--> DriverManager는 여러 드라이버들을 Vector에 저장하여 관리해주는 클래스이다

Class.forName("oracle.jdbc.driver.OracleDriver");

2. 어떤 오라클 서버에 연결할지?

-- oracle 데이터베이스에 연결하기 위해 jdbc를 사용

System.out.print("> 연결할 오라클 서버의 IP 주소 : ");
			String ip = sc.nextLine();

conn = DriverManager.getConnection("jdbc:oracle:thin:@"+ip+":1521:xe", "oracle address", "oracle passwd"); 

DriverManager.getConnection : 데이터베이스에 대한 연결을 설정하는 데 사용된다

  • 매개변수에 대한 분석
    url(문자열) :
    -- url 형식 --> 일반적으로 사용 중인 jdbc 드라이버와 연결 중인 데이터베이스에 따라 다르다

    jdbc url 숫자 '1521'은 oracle 데이터베이스가 들어오는 연결에 사용하는 기본 포트 번호를 나타낸다.
    hostname : oracle 데이터베이스 서버의 호스트 이름 또는 ip주소
    --> oracle 데이터베이스에 연결하려면 해당 시스템의 호스트 이름이나 ip 주소를 제공해야한다

  • oracle 데이터베이스에 연결할 때 jdbc:oracle:thin:@hostname: 1521: SID 에서 'hostname' 부분을 oracle 데이터베이스 서버의 실제 호스트 이름 또는 ip 주소를 바꿔야한다

    	- oracle 데이터베이스 인스턴스가 기본 '1521'이 아닌 다른 포트번호를 사용하는 경우 '1521'을 적절한 포트번호로 변경해야한다

    그러나 oracle 데이터베이스 인스턴스가 기본 포트 번호 '1521'을 사용하는 경우 이를 변경할 필요가 없다.

    • connection conn에서 DML의 기본 값은 auto commit이다

    conn.setAutoCommit(false); : false가 수동 commit으로 전환

    conn.setAutoCommit(true); : 자동 commit --> 대부분 안적는다


3. SQL문(편지)을 작성한다

System.out.println("> 글쓴이 : ");
			String name = sc.nextLine();

			System.out.println("> 글내용 : ");
			String msg = sc.nextLine();

String sql = " insert into tbl_memo(no, name, msg) "
+ " values(seq_memo.nextval,'" +name+ "', '" +msg+"')";
위와 같이 변수의 값을 직접 sql문에 대입시켜버리면 외부에 입력한 데이터 값이 보여지게 된다


해결방법
-> 위치홀더(?)를 사용한다

	⭐중요 		
			String sql = " insert into tbl_memo(no, name, msg) "
					+ " values(seq_memo.nextval,?,?)";
  • ?를 "위치홀더"라고 부른다
  • sql문 뒤에 ;를 넣으면 오류이다

⚠️⭐

  • SQL "INSERT"문의 경우 ".executeQuery()" 대신 ".executeUpdate()"를 사용해야한다
  • 변수의 값을 직접 sql문에 대입시켜버리면 외부에서 입력한 데이터값이 보여지므로 보안상 위험해진다

executeUpdate();

-> SQL문이 DML문(insert, update, delete, merge)이거나
SQL문이 DDL(create, drop, alter, truncate) 일 경우에 사용된다
SQL문이 DML문이라면 return 되어지는 값은 적용되어진 행의 개수를 리턴시켜준다

예를 들어,
insert into ... 하면 1 개행이 입력되므로 리턴값은 1 이 나온다.
update ... 할 경우에 update 할 대상의 행의 개수가 5 이라면 리턴값은 5 가 나온다.
delete ... 할 경우에 delete 되어질 대상의 행의 개수가 3 이라면 리턴값은 3 이 나온다.
SQL문이 DDL문이라면 return 되어지는 값은 무조건 0 이 리턴된다.

.executeQuery();

-> SQL문이 DQL(select)일 경우에 사용된다.


4. 연결한 오라클서버(conn)에 SQL문(편지)을 전달할 객체(우편배달부) 생성하기

pstmt = conn.prepareStatement(sql); //pstmt = conn.prepareStatement(sql); 이렇게 꼭 해줘야 함 
		pstmt.setString(1,name ); // 1 은 String sql 에서 첫번째 위치홀더(?)를 말한다. 첫번째 위치홀더(?)에 name 을 넣어준다.
		pstmt.setString(2,msg ); // 2 는 String sql 에서 두번째 위치홀더(?)를 말한다. 두번째 위치홀더(?)에 msg 을 넣어준다.
		
		
		
		System.out.println("~~ 확인용 sql => " + sql );

5. PreparedStatement 객체(우편배달부)는 작성된 SQL문(편지) 오라클 서버에 보내서 실행이 되도록 해야 한다.

int n = pstmt.executeUpdate(); //  중요하다

6. 사용하였던 자원을 반납하기

-> 반납의 순서는 생성순의 역순으로 한다


.....
catch (ClassNotFoundException e) {// Unhandled exception type ClassNotFoundException를 이미 올려다 두지 않고 파일이 없는 상태에서 해봤자 안된다 surrond
			System.out.println(">>> objdbc8.jar 파일이 없습니다 <<< ");
		
		}catch(SQLException e){
			e.printStackTrace();
		}
 finally {		
			
			try {
				if(pstmt != null) {
				pstmt.close();
				pstmt = null;
			}
			if(conn != null) {
				
				
				conn.close();
				conn = null;
			} 
		} catch (SQLException e) {
			
				e.printStackTrace();
			}
		
		}

0개의 댓글