가장 기본적인 DB 접근 API
SQL을 직접 문자열로 작성해야 함
Connection, PreparedStatement, ResultSet 등을 직접 관리해야 함
String sql = "SELECT * FROM user WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setLong(1, id);
ResultSet rs = ps.executeQuery();
👉 문제점: 코드가 장황하고, SQL/파라미터/매핑/리소스 해제가 번거로움.
JDBC의 불편함을 줄여준 SQL Mapper
XML이나 애노테이션에 SQL을 작성 → 매핑만 자동 처리
SQL은 여전히 직접 작성해야 하지만, 파라미터 바인딩, 결과 매핑이 편해짐
👉 장점: SQL을 내가 직접 제어할 수 있어서 DB 성능 튜닝에 강함
👉 단점: SQL을 계속 직접 써야 해서 반복적이고, 유지보수 어려움
SQL을 직접 쓰지 않고, 객체(Entity) 중심으로 DB 접근
CRUD는 메서드 호출만으로 처리 가능 (save(), findById() 등)
JPQL이라는 객체지향 쿼리 언어 제공 (SQL 비슷하지만 Entity 기준)
User user = em.find(User.class, 1L); // SELECT * FROM user WHERE id = 1
👉 장점: 생산성 ↑, DB 독립성 ↑ (DBMS 교체 쉬움)
👉 단점: 복잡한 동적 쿼리는 JPQL만으로 표현하기 어려움
QUser user = QUser.user;
List<User> result = queryFactory
.selectFrom(user)
.where(user.username.eq("kim"))
.fetch();
👉 장점:
동적 쿼리 작성이 쉽다 (조건문 if문 활용)
IDE 자동완성 지원
문자열 기반 JPQL보다 안전
👉 단점:
러닝커브 있음
코드량이 늘어남
JDBC → SQL과 자바를 직접 연결 (가장 저수준, 불편)
MyBatis → SQL은 내가 쓰되 매핑 편리하게 (SQL Mapper)
JPA → SQL도 숨기고 객체 중심으로 개발 (ORM)
QueryDSL → JPA의 단점을 보완, 타입 안전한 쿼리 제공 (ORM + 쿼리 빌더)
✅ 정리
JDBC : 직접 SQL 작성 (저수준)
MyBatis : SQL Mapper (SQL은 직접, 편의성 ↑)
JPA : ORM (SQL 자동 생성, 객체 중심 개발)
QueryDSL : JPA 보완 (타입 안전한 동적 쿼리 작성)