prepared statement vs statement

2023. 1. 22. 19:34카테고리 없음

1.Prepared Statement란 무엇인가?

 

pre 준비된 문장 , 쿼리가 미리 준비 되어있다는 의미이다.

이미 쿼리 실행계획 분석과 컴파일이 완료되어서 DBMS의 캐시에 준비되어있는 쿼리를 사용한다는 의미이다.

 

미리 SQL 쿼리문을 캐시해놓고 사용하기에 처리 속도가 빠르다.

 

먼저,  sql문을 작성시에는
1. 구문 분석
2. 컴파일
3. 실행 과정을  거친다.

sql문을 db에 전달을 하면  SQL 서버 엔진이 그것을 구문 분석하고 컴파일을 하고 실행을 하게 되는데
preparedStatement와 Statement와의 차이는 컴파일( 파싱)이 미리 되어 있는지 
아닌지 이다. pre는  처음 실행시면 1-3과정을 거친다면
이후 실행할때에는 3번 과정만 실행이 된다.

파싱 되어있는 것을 저장을 한다 그것을 캐싱 
 각 db마다 sql캐싱을 한다.

 

캐싱이 되는 위치는  DB 서버에 된다. 컴파일된 결과는 DB 서버의 메모리 또는 디스크에 저장이 되어있다.

 

### 클라이언트 사이드 기능이 아니라 ,  실제로 쿼리를 처리하는 방식,캐시등이 데이터 베이스에서 제공해주는 기능이라는 것을 우리는 알아야 한다. 

나중에 실행된 쿼리 로그들을 보면 서버쪽에서 쿼리 로그들을 남기는 경우들이 있는데 로그가 이상한 경우들이 많다.

? 이렇게 되어있는 것들 , 값을 넘겼는데 ? 되어있는 것이  preparedStatement되어서 넘어가서 그런것이다.

 

 

 

 

사전에 sql문장을 내장하기에 해커가 sql에 개입 할수가 없다.

 

 

SQL인젝션

 

해커가 SQL문을 변질시켜서 보내는데 항상 참으로 보낸다, 이것은 SQL문에 위배 되는 것이 아니기에 

이것을 이용해서 SQL문을 참으로 바꿔 회원 테이블에 마음대로 조작 할 수 있다.

 

 

인젝셔 하는 방법 

 

package mymain;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MyMain_DBTest_SQLInjection_YES{
	
	static {
	
		try {
			Class.forName( "oracle.jdbc.OracleDriver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	
	}

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String user= "test";
	    String pwd="test";
	    
	    Connection conn = DriverManager.getConnection(url, user, pwd);
	    
	    
	    Statement stmt = conn.createStatement();
	    
	    
	    String sql = "select * from test_member where id='one' and pwd='1234'"+"or 1=1";//둘중 하나만 참이여도 TURE
	    ResultSet rs = stmt.executeQuery(sql);
	    
	    
	    while(rs.next()) {
	    	int 	idx 	= rs.getInt("idx");
	    	String 	id		= rs.getString("id");
	    	String 	pwd1 	= rs.getString("pwd");
	    	String 	name 	= rs.getString("name");
	    	
	    	System.out.printf("[%d-%s-%s-%s]\n",idx,id,pwd1,name);
	    	
	    }
	    
	    
	   
	
	 
	    
	 
	    rs.close();
	    stmt.close();
	    conn.close();
	}

}
[1-one-1234-일길동]
[2-two-1234-이길동]
[3-three-1234-삼길동]
[4-four-1234-사길동]
[5-five-1234-오길동]

이렇게 회원 목록이 나온다

Statement보다 Preparedstatement을 사용해야 하는 이유(성능, 보안 측면) (velog.io).