[KB IT's Your Life 7기] 14주차 교육 후기: JDBC
2026. 6. 8. 20:31

 


 

 

 

앞서 DB 파트에서 DBMS 개요와 데이터베이스 모델링을 다뤘다면,

이번 주차부터는 드디어 Java와 DB를 연결하는 단계로 넘어왔습니다

프론트엔드, DB를 다 배우고 나서 이 둘을 이어주는 파트가 나온다는 게

커리큘럼 구성 자체가 꽤 잘 짜여있다는 생각이 들었습니다

이번 주차에서 다룬 내용은 하나입니다

 

 

-------- JDBC 프로그래밍 --------

 


 

1. JDBC란?

 

1. JDBC 개념

 

JDBC는 Java Database Connectivity의 약자로,

Java에서 데이터베이스와 연결해서 입출력을 지원하는 기술입니다

 

핵심은 DBMS의 종류와 상관없이 동일하게 사용할 수 있는

클래스와 인터페이스로 구성되어 있다는 점입니다

 

Oracle을 쓰든, MySQL을 쓰든, MariaDB를 쓰든

애플리케이션 코드는 동일한 JDBC 인터페이스를 사용하고,

각 DBMS에 맞는 JDBC Driver가 중간에서 실제 통신을 담당합니다

 

 

그래서 DB를 바꿔도 애플리케이션 코드를 크게 수정할 필요가 없다는 장점이 있습니다

이 구조가 바로 앞서 배웠던 DBMS 독립성과 연결되는 부분입니다

 

 

2. JDBC 개발 절차

 

 

JDBC로 DB와 통신하는 절차는 크게 6단계로 나뉩니다

 

1단계는 JDBC 드라이버 로드입니다

Class.forName()을 사용해서 드라이버 클래스를 메모리에 올립니다

드라이버가 없으면 ClassNotFoundException이 발생합니다

 

2단계는 데이터베이스 연결입니다

DriverManager.getConnection()으로 Connection 객체를 생성합니다

연결 문자열 형식은 jdbc:mysql://[host]:[포트]/[db이름] 입니다

 

3단계는 Statement 생성, 4단계는 SQL문 전송, 5단계는 결과 받기, 6단계는 연결 해제입니다

 

SELECT문 실행에는 executeQuery()를 사용해서 ResultSet을 반환받고,

INSERT, UPDATE, DELETE에는 executeUpdate()를 사용해서 영향받은 행 수를 반환받습니다

 

 

 

 

 

2. 환경 설정

 

1. 데이터베이스 및 사용자 준비

 

먼저 MySQL에서 실습용 데이터베이스와 사용자를 준비합니다

CREATE DATABASE jdbc_ex;

CREATE USER 'scoula'@'%' IDENTIFIED BY '1234';
GRANT ALL PRIVILEGES ON jdbc_ex.* TO 'scoula'@'%';
FLUSH PRIVILEGES;

 

GRANT로 권한을 부여하고 FLUSH PRIVILEGES로 적용하는 과정입니다

 

 

2. Gradle 프로젝트 설정

 

 

IntelliJ에서 Gradle 프로젝트를 생성한 뒤,

build.gradle에 MySQL Connector와 Lombok 의존성을 추가합니다

 

implementation 'com.mysql:mysql-connector-j:8.3.0'
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'

 

수정 후에는 반드시 Sync를 실행해줘야 합니다

그리고 Lombok을 사용하려면 IntelliJ 설정에서 Annotation Processing도 활성화해야 합니다

이전에 IntelliJ Gradle JDK 설정 오류를 다뤘던 경험이 있어서

이번에는 Gradle 8.x에 맞게 JDK 17로 미리 맞춰놓고 진행했습니다

 

 

3. IntelliJ Datasource 설정

 

 

IntelliJ에는 DB 연결을 직접 관리할 수 있는 Datasource 기능이 있습니다

Database 탭에서 MySQL을 선택하고

Host, Port, User, Password, Database를 입력하면

IDE 내에서 바로 쿼리를 작성하고 실행할 수 있습니다

 

Test Connection으로 연결을 확인하면 Succeeded와 함께

MySQL 버전, 드라이버 정보, Ping 응답 시간이 표시됩니다

 

 


 

 

3. 핵심 클래스와 실습

 

1. JDBCUtil 모듈화

 

DB 연결과 해제는 어디서든 반복적으로 필요한 코드입니다

그래서 이걸 common 패키지의 JDBCUtil 클래스로 모듈화합니다

application.properties 파일에 연결 정보를 분리해두고

JDBCUtil의 static 블록에서 Properties를 읽어 Connection을 생성합니다

getConnection()으로 연결을 가져오고, close()로 해제합니다

 

이렇게 하면 나중에 DB 정보가 바뀌어도

코드 대신 properties 파일만 수정하면 됩니다

 

2. Statement vs PreparedStatement

 

SQL을 실행하는 방법에는 Statement와 PreparedStatement 두 가지가 있습니다

 

Statement는 SQL 문자열을 그대로 실행합니다

값을 변수로 대체하려면 문자열 연결 연산자로 직접 이어붙여야 하는데,

이 방식은 SQL Injection에 취약하고 코드 가독성도 떨어집니다

 

PreparedStatement는 SQL에 ?로 파라미터를 표시하고

setString(), setInt() 등으로 값을 안전하게 바인딩합니다

보안과 가독성 측면에서 PreparedStatement를 사용하는 것이 훨씬 낫습니다

 

 

3. ResultSet

 

 

SELECT 쿼리의 결과는 ResultSet으로 받습니다

커서는 최초에 beforeFirst 위치에 있고, next()를 호출할 때마다 한 행씩 이동합니다

 

더 이상 행이 없으면 next()가 false를 반환합니다

각 컬럼의 값은 getString("컬럼명"), getInt("컬럼명") 등으로 추출합니다

 

 


 

 

4. VO 패턴과 DAO 패턴

 

1. VO 패턴

 

VO는 Value Object의 약자로, 특정 테이블의 한 행을 매핑하는 클래스입니다

클래스 정의가 테이블, 필드들이 컬럼들, 인스턴스가 한 행에 해당합니다

 

UserVO 클래스에는 id, password, name, role 필드가 있고,

Lombok의 @Data, @NoArgsConstructor, @AllArgsConstructor 어노테이션으로

getter, setter, 생성자를 자동으로 생성합니다

 

 

2. DAO 패턴

 

 

DAO는 Data Access Object의 약자로,

데이터베이스에 접근하여 실질적인 연동 작업을 담당하는 클래스입니다

테이블에 대한 CRUD 연산을 처리하며, 인터페이스를 먼저 정의한 후 구현 클래스를 작성합니다

 

UserDao 인터페이스에는 create, getList, get, update, delete 메서드가 정의되어 있고,

UserDaoImpl에서 각 메서드를 PreparedStatement로 구현합니다

ResultSet을 UserVO로 변환하는 map() 메서드를 별도로 만들어두면

여러 조회 메서드에서 재사용할 수 있어서 코드가 훨씬 깔끔해집니다

 

 

마지막으로 IntelliJ의 Generate Test 기능을 활용하면

UserDao 인터페이스 기준으로 테스트 클래스를 자동으로 생성할 수 있습니다

 

각 메서드에 @Order 어노테이션으로 실행 순서를 지정하면

insert → select → update → delete 순서대로 테스트가 진행됩니다

 

 


 

 

 

이번 주차는 개인적으로 가장 체감이 컸던 주차였습니다

React로 프론트엔드를 개발할 때 DB 연동은 항상 백엔드가 처리해줬는데

JDBC를 통해 Java 코드가 직접 DB와 통신하는 전체 흐름을 처음으로 밑바닥부터 구현해봤습니다

 

특히 VO와 DAO 패턴으로 코드를 분리하는 구조가

나중에 배울 MyBatis나 JPA 같은 ORM의 기반이 될 것 같아서

확실히 이해하고 넘어가야겠다는 생각이 들었습니다

 

Statement보다 PreparedStatement를 써야 하는 이유,

ResultSet 커서가 처음에 beforeFirst에 위치하는 구조 같은 부분들이

직접 코드를 짜봐야 머릿속에 남는 것들이라서

이번 주 실습이 꽤 유익했습니다

 

다음 주차도 기대하면서, 수료까지 파이팅!!!!