[Java] 122. JDBC 성능 최적화
1. PreparedStatement 사용의 장점
2. 연결 풀(Connection Pool)과 데이터 소스(Data Source)
1. PreparedStatement 사용의 장점
PreparedStatement는 SQL 쿼리를 미리 컴파일하고, 동일한 쿼리를 반복해 실행할 때 효율적으로 사용할 수 있는 인터페이스이다.
(1) 성능 향상
-쿼리 컴파일: SQL 쿼리를 미리 컴파일 해, 쿼리를 여러번 실행할 때 컴파일 시간을 절약할 수 있다.
-쿼리 계획 재사용: 동일한 쿼리를 반복적으로 실행할 때, 쿼리 계획을 재사용하여 실행 시간을 단축할 수 있다.
(2) 보안 향상
-SQL 인젝션 방지: 쿼리와 데이터가 분리되어 있어, SQL 인젝션 공격을 방지할 수 있다.
* 사용 예시
private static void viewQuizQuestion(Connection conn) {
try (PreparedStatement pstmt= conn.prepareStatement(VIEW_QUIZ);){
ResultSet resultSet = pstmt.executeQuery(); // ResultSet을 반환한다.
while(resultSet.next()) { // next:다음 값 반환
System.out.println("문제 ID : "+resultSet.getInt("id"));
System.out.println("문제 : "+resultSet.getString("question"));
System.out.println("정답 : "+resultSet.getString("answer"));
if(!resultSet.isLast()) {
System.out.println();
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Static{} 블록 - 정적 초기화 블록
// 클래스가 처음 로드될 때 한 번 실행된다.
// 정적 변수의 초기화나 복잡한 초기화 작업을 수행할 때 사용
// static {} 블록 안에 예외를 던질 수도 있다.
static {
System.out.println("------------");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
package ch01;
import java.util.Scanner;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class SQLInjectionExample {
public static void main(String[] args) {
try (Connection conn = DBConnectionManager.getConnection()) {
Scanner scanner = new Scanner(System.in);
System.out.print("사용자 이름을 입력하세요 : ");
String username = scanner.nextLine();
// 취약한 SQL 쿼리 작성해보기 (SQL 인젝션이 가능)
String query = "SELECT * FROM users WHERE name = " + username + " ";
String query2 = "SELECT * FROM users WHERE name = ?";
try (Statement stmt = conn.createStatement();
//Statement 사용과 인젝션 공격 확인
//ResultSet resultSet=stmt.executeQuery(query);
//SQL 인젝션 방지를 위한 PreparedStatement의 사용
PreparedStatement pstmt=conn.prepareStatement(query2)) {
pstmt.setString(1, username);
ResultSet resultSet = pstmt.executeQuery();
while (resultSet.next()) {
System.out.println("사용자 이름 " + resultSet.getString("name"));
System.out.println("사용자 메일 " + resultSet.getString("email"));
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} // end of main
} // end of class
package ch01;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnectionManager{
private static final String URL = "jdbc:mysql://localhost:3306/demo3?serverTimezone=Asia/Seoul";
private static final String USER = "root";
private static final String PASSWORD = "asd123";
// static {} 블록 - 정적 초기화 블록
// 클래스가 처음 로드될 때 한 번 실행 됩니다.
// 정적 변수의 초기화나 복잡한 초기화 작업을 수행할 때 사용
// static {} 블록안에 예외를 던질 수도 있다.
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 정적 메서드(함수) 커넥션 객체를 리턴하는 함수를 만들어 보자
static Connection getConnection() throws SQLException{
return DriverManager.getConnection(URL,USER,PASSWORD);
}
}
2. 연결 풀(Connection Pool)과 데이터 소스(Data Source)
(1) 데이터베이스 연결의 생애주기
-
*커넥션 풀(Connection Pool)과 데이터 소스(Data Source)는 데이터베이스 연결 관리를 효율적으로 하기 위해 사용하는 개념이다.
(2) 연결 풀(Coonection Pool)
-정의: 데이터베이스 연결 풀은 일정 수의 데이터베이스 연결을 미리 생성해두고, 애플리케이션에서 필요할 때마다 이 연결을 재사용하는 기술이다.
-목적: 데이터베이스 연결을 효율적으로 관리하여 성능을 향상시키고, 데이터베이스 서버의 부하를 줄인다.
-작동 원리: 애플리케이션이 데이터베이스 연결을 요청하면, 연결 풀에서 사용 가능한 연결을 반환한다. 사용이 끝난 연결은 폐기되지 않고, 다시 연결 풀에 반환되어 재사용된다.
*핵심 정리*
(3) 데이터 소스 (Data Source)
-정의: 데이터 소스는 데이터베이스 연결 정보를 캡슐화한 객체로, 애플리케이션이 데이터베이스와 상호작용할 때 사용된다. 일반적으로 데이터 소스는 연결 풀을 포함하여 데이터베이스 연결을 관리한다.
-목적: 데이터 소스는 데이터베이스 연결 설정을 단순화하고, 연결 풀을 통해 효율적인 연결 관리를 제공한다.
-사용 방법: 데이터 소스를 설정하고, 애플리케이션에서 데이터 소스를 통해 데이터베이스 연결을 요청한다.
*핵심 정리*
(4) 연결 풀과 데이터 소스의 관계
-통합 관리:
-연결 추상화:
'Java > 네트워크 통신' 카테고리의 다른 글
[Java] 124. JDBC에서의 예외 처리 (0) | 2024.06.17 |
---|---|
[Java] 123. HikariCP 라이브러리를 프로젝트에 추가하기 (0) | 2024.06.17 |
[Java] 121. JDBC를 활용한 CRUD와 SOLID 원칙 (2) (0) | 2024.06.14 |
[Java] 120. JDBC를 활용한 CRUD와 SOLID 원칙 (1) (0) | 2024.06.14 |
[Java] 119. 트랜잭션과 배치 처리 (0) | 2024.06.13 |