이번 글에서는 JDBC를 배우면서 도서관리 CRUD 모듈을 만드는 중 알게되었던 내용과 추가로 알게된 점을 정리해보려 한다
🧐JDBC란?
JDBC는 자바로 데이터베이스에 접근하여 데이터를 관리할 수 있도록 하는 자바 API이다.
데이터베이스는 종류가 다양하고, 약간 통신방식이 다르다, JDBC를 사용하면 하나의 통일된 방식으로 데이터베이스 작업을 처리할 수 있게 해준다. 이때 JDBC가 그 통역가 역할을 한다,
그렇다면 JDBC는 어떻게 자바와 데이터베이스 사이를 연결해줄까? 그림으로 확인해보자

JDBC API 는 Connection, PreparedStatement 등 모든 DB에서 공통으로 사용할 기능들을 제공한다.
JDBC Driver는 JDBC API와 DB를 연결해주는 역할을 한다.
✅JDBC API는 다음과 같이 작동한다

1. 드라이버 로딩
JDBC를 사용하기 위해서 먼저 사용할 데이터베이스에 맞는 JDBC 드라이버를 로드해야한다.
2. 데이터베이스 연결
드라이버 로딩 후에는 DriverManager.getConnection(URL, username, password) 메서드를 사용해 연결한다
3. state 객체 생성
연결이 설정되면 SQL 쿼리를 보내기 위해 Statement 또는 PreparedStatement 객체를 생성한다
4. 쿼리 실행 및 결과 받기
state 객체를 통해 SQL 쿼리를 데이터베이스로 전송하여 실행한다.
executeQuery() 메서드는 SELECT 쿼리에 사용되며, 결과는 ResultSet 객체로 반환한다.
executeUpdate 메서드는 INSERT, UPDATE, DELETE 쿼리에 사용되며, 영향을 받은 행의 개수를 int 타입으로 반환한다.
5. 결과 처리 및 자원 반납
ResultSet으로 받은 결과는 while(rs.next()) 루프로 한 줄 씩 읽어와서 사용한다
사용이 완료된 ResultSet, Statement, Connection 객체는 반드시 닫아주어야 한다. 객체.close() 로 닫을 수 있다.
🔍JDBC를 더 잘 사용하는 방법(DAO, DTO 이용하기)
✅DTO란?
nestjs에서의 dto를 기록했듯 개념은 동일하다 간략하게 말하자면
데이터베이스의 한 행에 해당하는 데이터를 담기 위해 만들어진 객체로, dto의 멤버 변수들은 데이터베이스의 각 컬럼에 해당한다
데이터를 전달할 때 DTO에 모든 정보를 담아 한번에 깔끔하게 전달할 수 있다.

✅DAO란?
데이터베이스에 접근하는 객체로, CRUD(생성, 조회, 수정, 삭제) 작업을 실제로 수행한다.
모든 SQL 코드(쿼리)는 DAO 안에서 작성되고 사용한다.
DAO를 사용하면 DB를 모르는 개발자도 DAO의 메서드만 호출하면 편하게 기능을 이용할 수 있다(협업 시 이점이 큼).
✅DAO 인터페이스 왜 사용하나?

DAO가 어떤 기능들을 제공해야 하는지 미리 정해놓는 인터페이스이다.
인터페이스를 사용하면 느슨한 결합이 만들어져서 유지보수와 기능 확장에 큰 이점이 있다.
나중에 데이터베이스를 Oracle에서 MySQL로 바꾼다고 가정하자 그러면 이때 MySQLBookDAO라는 새로운 DAO를 만들어 해당 인터페이스의 규칙대로 구현만하면 메인 코드는 큰 변경 필요없이 부품만 교체하듯 바꿔주기만 하면 된다. 이로써 유지보수와 기능확장에 편의를 챙길 수 있다.
➕수업중에서 DAO 변수에 관해 추가로 알게된 점
DAO에서 미리 변수들을 선언해놓고 사용을 했었다.
그런데 이 경우 간단한 앱에서는 괜찮지만, 여러 사람이 동시에 사용하는 경우에는 주의해야 한다고 한다.
왜냐하면 여러 사용자가 동시에 DAO 객체를 사용할 때 이 변수들을 공유하게 되어 데이터가 꼬여 심각한 문제가 발생할 수 있기 때문이다. 그래서 데이터를 받는 변수들은 각 메서드 내의 지역 변수를 선언해서 사용하는 것이 가장 안전하고 표준적인 방법이라고한다.


🧐DB 연결은 왜, 언제, 어떻게 닫아야 하는가?
- 닫아야 하는 이유: 데이터베이스는 동시에 연결할 수 있는 사용자의 수가 제한되어 있다.
사용이 끝난 연결을 닫지 않으면, 연결 자원이 계속 낭비되다가 결국 새로운 사용자가 접속하지 못하는 '자원 고갈' 상태가 된다. - 언제 닫아야 하는가: 사용한 직후, 더 이상 필요 없을 때 닫아야 한다. 예외가 발생하더라도 반드시 닫아야 하므로, try-catch-finally 구문의 finally 블록 안에서 닫는 것이 정석이다.
- 닫을 때 조심할 점: 자원은 생성된 순서의 역순으로 닫는 것이 안전하다.
- ResultSet → PreparedStatement → Connection
✅PreparedStatement의 SQL Injection 예방
Statement는 사용자의 입력을 SQL 코드의 일부로 그대로 이어 붙이기 때문에, 해커가 악의적인 구문을 주입하면 문법이 파괴되어 원치 않는 데이터가 노출될 수 있다. 반면, PreparedStatement는 SQL의 틀(?)을 미리 만들어 놓고, 사용자의 입력은 문법이 아닌 단순 데이터(값)로만 취급한다. 덕분에 악의적인 코드가 주입되어도 원래의 쿼리 문법에 영향을 주지 않아 SQL Injection 공격을 원천적으로 막을 수 있다. 보안을 위해 PreparedStatement 사용은 선택이 아닌 필수이다.

'Archive > Java 풀스택 아카데미' 카테고리의 다른 글
| [TIL] 8. 8월 디자인패턴(싱글톤, 전략패턴) (3) | 2025.08.31 |
|---|---|
| [TIL] 7. 8월 알고리즘(유클리드 호제법) (2) | 2025.08.25 |
| [TIL] 5. 8월 JAVA(SET) (4) | 2025.08.09 |
| [TIL] 4. 7월 5주차 - JAVA(상속) (4) | 2025.08.02 |
| [TIL] 3. 7월 4주차 - React (학습 중에 알게된 것들) (2) | 2025.07.27 |