6주차 Unit 3.3 — JDBC가 해결하지 않는 것

Psj·2026년 5월 29일

F-lab

목록 보기
193/240

Unit 3.3 — JDBC가 해결하지 않는 것

F-LAB JAVA · 6주차 · Phase 3 · JDBC 표준화의 등장
🏆 Phase 3 완주 — JDBC 의 한계와 상위 프레임워크의 등장


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • JDBC 의 한계 는?
  • SQL 문법 차이 (LIMIT vs ROWNUM) 는?
  • 자동 증가 컬럼 문법 차이는?
  • 페이징 처리 차이는?
  • 상위 프레임워크 (JdbcTemplate/JPA/MyBatis) 등장 배경은?
  • "JDBC 표준화됐는데 왜 ORM?" 의 답은?
  • ORM 이 SQL 차이 해결 하는 방식 (Dialect) 은?
  • JdbcTemplate / MyBatis / JPA 비교는?
  • Phase 3 전체 의 종합은?

🎯 핵심 한 문장

JDBC 는 API 는 통일했지만 SQL 문법 차이 (LIMIT vs ROWNUM, AUTO_INCREMENT vs SEQUENCE) 는 그대로 두었기에 DB 마다 SQL 을 다르게 써야 하며, 이를 해결하기 위해 JdbcTemplate (반복 제거), MyBatis (SQL 외부화), JPA/Hibernate (Dialect 로 SQL 자동 생성) 같은 상위 프레임워크가 등장했다.
JDBC 는 연결·실행·결과 처리는 통일했지만 SQL 문법 차이는 그대로 두었다.
대표 차이는 (1) LIMIT (MySQL) vs ROWNUM/OFFSET FETCH (Oracle), (2) AUTO_INCREMENT (MySQL) vs SEQUENCE (Oracle), (3) 페이징 처리 방식 등이다.
또 JDBC 는 매 쿼리마다 try/catch/finally 자원 관리 코드를 반복해야 하는 부담도 남겨 두었다.
이를 해결하기 위해 상위 프레임워크가 등장했다 — JdbcTemplate (Spring) 은 JDBC 반복 코드를 제거하고, MyBatis 는 SQL 을 XML 로 분리해 DB 별 분기를 가능하게 하며, JPA/HibernateDialect (방언) 로 SQL 자체를 자동 생성해 SQL 문법 차이를 거의 다룰 필요가 없게 한다.

비유 — 표준 콘센트는 통일됐는데 전압이 다름

JDBC 가 해결하지 않은 것 = 전압 차이:

JDBC = 콘센트 표준화 (Unit 3.2):
  - 플러그 모양 통일 (API)
  - 어디서든 꽂힘

JDBC 가 안 한 것 = 전압:
  - 한국 220V, 미국 110V (SQL 문법)
  - 꽂혀도 동작 다름

SQL 문법 차이:
  - LIMIT 10 (MySQL, "10개")
  - ROWNUM (Oracle, 다른 문법)
  - 같은 일, 다른 표현

JDBC 반복:
  - 매번 try/catch/finally
  - 자원 관리 보일러플레이트

해결 (상위 프레임워크):
  - JdbcTemplate (반복 제거)
  - MyBatis (SQL 외부화)
  - JPA/Hibernate (Dialect, SQL 자동)
    - 220V/110V 자동 변환 어댑터

→ JDBC = API 통일 (콘센트), SQL 차이 + 반복 남음 → 상위 프레임워크 (Dialect/템플릿).


🧭 9개 섹션 로드맵

1. JDBC의 한계
2. SQL 문법 차이 (LIMIT vs ROWNUM)
3. 자동 증가/페이징 차이
4. JDBC 반복 코드 부담
5. 상위 프레임워크 등장
6. JdbcTemplate
7. MyBatis
8. JPA/Hibernate (Dialect)
9. Phase 3 완주 정리

1️⃣ JDBC의 한계

1.1 한계 정리

JDBC 한계:

1. SQL 문법 차이 그대로
2. 반복 코드 (try/catch/finally)
3. ResultSet → 객체 매핑 수동
4. SQL 문자열 (오타 위험)

1.2 통일/미통일

JDBC 통일 vs 미통일:

통일 (3.2):
  - 연결/실행/결과 API
  - DB 무관 코드

미통일 (3.3):
  - SQL 문법 (DB별)
  - 코드 반복 부담
  - 매핑 부담

1.3 왜 SQL 은 통일 X

왜 SQL 은 통일 X:

  SQL 자체가:
    - DB 별 방언 (Dialect)
    - 표준 (ANSI) 있지만 차이
    - JDBC 는 API 만

→ SQL 은 사용자 책임

1.4 ILIC 의 맥락

JDBC 한계 (ILIC)

ILIC 가 MySQL → Oracle (JDBC 사용):

  ✓ 통일된 부분:
    - DriverManager.getConnection (OK)
    - prepareStatement (OK)
    - ResultSet (OK)
    → 코드 동일

  ❌ 통일 안 된 부분:
    - SQL: LIMIT → ROWNUM 변경 필요
    - AUTO_INCREMENT → SEQUENCE
    - 페이징 쿼리 재작성

  + 모든 메서드에 try/catch/finally 반복
  + ResultSet → Shipment 객체 매핑 매번

→ JDBC 가 충분치 않음 (상위 필요)

1.5 자기 점검 답변

JDBC의 한계는?

:
1. 한계:

  • SQL 차이/반복/매핑
  1. 통일/미통일:

    • API 통일, SQL 미통일
  2. :

    • SQL 자체가 방언
  3. 결과:

    • 상위 프레임워크 필요

2️⃣ SQL 문법 차이 (LIMIT vs ROWNUM)

2.1 LIMIT vs ROWNUM

페이징 문법 차이:

MySQL/PostgreSQL:
  SELECT * FROM shipments LIMIT 10 OFFSET 20;

Oracle (구버전):
  SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (...) a
    WHERE ROWNUM <= 30
  ) WHERE rn > 20;

Oracle 12c+ / SQL Server:
  SELECT * FROM shipments
  OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

2.2 같은 일, 다른 문법

같은 일, 다른 문법:

  의도: 21~30번째 행

  MySQL: LIMIT 10 OFFSET 20
  Oracle 구: ROWNUM 서브쿼리
  Oracle 신: OFFSET FETCH

→ DB 별 학습 필요

2.3 DB 이식성 문제

DB 이식성 문제:

  DB 교체:
    - SQL 재작성
    - 페이징 부분 다시
    - 테스트

→ 코드 변경 필요

2.4 ILIC 의 맥락

// SQL 문법 차이 (ILIC)
public class ShipmentDao {
    // MySQL 페이징
    public List<Shipment> findPageMysql(int offset, int size) 
            throws Exception {
        String sql = "SELECT * FROM shipments " +
                     "ORDER BY id LIMIT ? OFFSET ?";
        // MySQL 문법
        return null;
    }
    
    // Oracle 페이징 (다른 SQL)
    public List<Shipment> findPageOracle(int offset, int size) 
            throws Exception {
        String sql = "SELECT * FROM (" +
                     "  SELECT a.*, ROWNUM rn FROM (" +
                     "    SELECT * FROM shipments ORDER BY id" +
                     "  ) a WHERE ROWNUM <= ?" +
                     ") WHERE rn > ?";
        // Oracle 구버전 (복잡)
        return null;
    }
    // 같은 페이징, SQL 두 벌 (JDBC 만으론 통일 X)
}
class Shipment {}

2.5 자기 점검 답변

SQL 문법 차이 (LIMIT vs ROWNUM) 는?

:
1. 페이징:

  • LIMIT vs ROWNUM/OFFSET FETCH
  1. 같은 일:

    • 다른 문법
  2. 이식성:

    • DB 교체 시 재작성
  3. DB 별:

    • 학습 필요

3️⃣ 자동 증가/페이징 차이

3.1 자동 증가

자동 증가:

MySQL/PostgreSQL:
  CREATE TABLE ...(
    id BIGINT AUTO_INCREMENT PRIMARY KEY
  );

Oracle:
  CREATE SEQUENCE shipment_seq START WITH 1;
  INSERT INTO ...(id, ...) VALUES (shipment_seq.NEXTVAL, ...);

SQL Server:
  id BIGINT IDENTITY(1,1) PRIMARY KEY

3.2 ID 생성 방식

ID 생성 방식 차이:

MySQL: AUTO_INCREMENT (테이블 옵션)
Oracle: SEQUENCE (별도 객체)
SQL Server: IDENTITY (컬럼 옵션)

→ DB 마다 다름

3.3 기타 차이

기타 SQL 차이:

  - 날짜/시간 함수
    - MySQL: NOW(), CURDATE()
    - Oracle: SYSDATE
  
  - 문자열 결합
    - MySQL: CONCAT()
    - Oracle: ||, CONCAT()
  
  - NULL 처리
    - MySQL: IFNULL()
    - Oracle: NVL()

3.4 JDBC 표준화 시도

JDBC 표준화 시도:

  Statement.RETURN_GENERATED_KEYS:
    - 자동 키 조회 통일
    - 일부 표준화

→ 하지만 SQL 자체는 그대로

3.5 ILIC 의 맥락

-- MySQL (ILIC)
CREATE TABLE shipments (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    bl_no VARCHAR(50),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Oracle (다른 문법)
CREATE TABLE shipments (
    id NUMBER(19) PRIMARY KEY,
    bl_no VARCHAR2(50),
    created_at DATE DEFAULT SYSDATE
);
CREATE SEQUENCE shipment_seq START WITH 1;

-- INSERT 도 다름
-- MySQL: INSERT INTO shipments(bl_no) VALUES('BL001');  (자동 ID)
-- Oracle: INSERT INTO shipments(id, bl_no) 
--         VALUES(shipment_seq.NEXTVAL, 'BL001');

-- → ILIC 가 멀티 DB 지원 시 SQL 차이 부담
-- → ORM/MyBatis 등 도움 필요

3.6 자기 점검 답변

자동 증가 컬럼 문법 차이는?

:
1. 자동 증가:

  • MySQL: AUTO_INCREMENT
  • Oracle: SEQUENCE
  1. ID 생성:

    • DB 마다 다름
  2. 기타:

    • 날짜/문자열/NULL
  3. JDBC:

    • 일부 표준화

4️⃣ JDBC 반복 코드 부담

4.1 반복 코드

// JDBC 반복 코드
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = DriverManager.getConnection(url, user, pwd);
    stmt = conn.prepareStatement(sql);
    stmt.setLong(1, id);
    rs = stmt.executeQuery();
    while (rs.next()) {
        // 결과 처리
    }
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    if (rs != null) try { rs.close(); } catch (SQLException e) { }
    if (stmt != null) try { stmt.close(); } catch (SQLException e) { }
    if (conn != null) try { conn.close(); } catch (SQLException e) { }
}

4.2 보일러플레이트

보일러플레이트:

  매 쿼리마다 똑같이:
    - try/catch/finally
    - 자원 해제 (역순)
    - null 체크

→ 본 로직 < 인프라 코드

4.3 실수 위험

실수 위험:

  - close 누락 (자원 누수)
  - 예외 처리 누락
  - 역순 안 함

→ Connection 누수 발생

4.4 5주차 관점

5주차 관점:

  변하지 않는 흐름 + 변하는 부분:
    - 흐름: 연결/해제 (반복)
    - 변동: SQL/매핑

→ 템플릿 메소드 / 전략 패턴
→ JdbcTemplate (Phase 7)

4.5 ILIC 의 맥락

// JDBC 반복 코드 (ILIC, 431 API 마다?)
public class ShipmentDao {
    public Shipment get(Long id) throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = DriverManager.getConnection(url, user, pwd);
            stmt = conn.prepareStatement(
                "select * from shipments where id = ?");
            stmt.setLong(1, id);
            rs = stmt.executeQuery();
            if (rs.next()) {
                Shipment s = new Shipment();
                s.setId(rs.getLong("id"));
                return s;
            }
            return null;
        } catch (SQLException e) {
            throw e;
        } finally {
            if (rs != null) try { rs.close(); } catch (SQLException e) { }
            if (stmt != null) try { stmt.close(); } catch (SQLException e) { }
            if (conn != null) try { conn.close(); } catch (SQLException e) { }
        }
    }
    
    public void add(Shipment s) throws Exception {
        // 같은 try/catch/finally 또 반복
    }
    
    public void update(Shipment s) throws Exception {
        // 또 반복
    }
    // 431 API 마다 이걸? → JdbcTemplate 필요
    String url, user, pwd;
}
class Shipment {
    void setId(Long id) {}
}

4.6 자기 점검 답변

JDBC 반복 코드 부담은?

:
1. 반복:

  • try/catch/finally
  1. 보일러플레이트:

    • 본 로직보다 김
  2. 위험:

    • close 누락, 누수
  3. 해결:

    • JdbcTemplate (Phase 7)

5️⃣ 상위 프레임워크 등장

5.1 등장 배경

상위 프레임워크 등장:

  JDBC 의 한계:
    - SQL 차이
    - 반복 코드
    - 매핑 부담

  → 상위 계층 추상화 필요

5.2 세 가지 흐름

세 가지 흐름:

1. JdbcTemplate (Spring)
   - 반복 코드 제거
   - SQL 은 직접

2. MyBatis
   - SQL 외부화 (XML)
   - DB 별 분기

3. JPA/Hibernate
   - ORM (객체 ↔ 테이블)
   - SQL 자동 생성

5.3 추상화 수준

추상화 수준:

  JDBC: 저수준
    ↓
  JdbcTemplate: 중간 (SQL 직접)
    ↓
  MyBatis: 중간 (SQL 외부)
    ↓
  JPA: 고수준 (SQL 자동)

5.4 선택 기준

선택 기준:

  단순/성능: JdbcTemplate
  SQL 제어/DB 차이: MyBatis
  생산성/객체 중심: JPA

→ 프로젝트 성격

5.5 ILIC 의 맥락

상위 프레임워크 선택 (ILIC)

ILIC = Spring Boot + JPA + JdbcTemplate:
  - 일반 CRUD: JPA (Spring Data JPA)
    - 객체 중심
    - SQL 자동
  - 복잡한 통계/리포트: JdbcTemplate
    - 성능
    - SQL 직접 제어

  102 테이블 + 431 API:
    - JPA 로 대부분 처리
    - 특수 케이스만 JdbcTemplate
    - 둘 다 JDBC 위에서 동작

→ 상위 프레임워크가 JDBC 한계 보완

5.6 자기 점검 답변

상위 프레임워크 등장 배경은?

:
1. 등장 배경:

  • JDBC 한계
  1. 세 흐름:

    • JdbcTemplate/MyBatis/JPA
  2. 추상화 수준:

    • 저수준 → 고수준
  3. 선택:

    • 프로젝트 성격

6️⃣ JdbcTemplate

6.1 JdbcTemplate

JdbcTemplate (Spring):

  JDBC 반복 코드 제거:
    - 자원 관리 자동
    - 예외 변환
    - SQL 만 작성

6.2 동작

JdbcTemplate 동작:

  - Connection 자동 (DataSource)
  - PreparedStatement 자동
  - ResultSet 자동
  - 자원 해제 자동
  - 예외 → RuntimeException

6.3 사용

// JdbcTemplate 사용 (간결)
public List<Shipment> findAll() {
    return jdbcTemplate.query(
        "select * from shipments",
        (rs, rowNum) -> {
            Shipment s = new Shipment();
            s.setId(rs.getLong("id"));
            return s;
        }
    );
}
// try/catch/finally 없음, 자원 자동

6.4 SQL 은 직접

SQL 은 직접:

  JdbcTemplate:
    - 반복 제거 O
    - SQL 자동 X (직접)
    - DB 차이 있음

→ Phase 7 에서 상세

6.5 ILIC 의 맥락

// JdbcTemplate (ILIC 일부 사용)
@Repository
public class ShipmentStatisticsDao {
    private final JdbcTemplate jdbcTemplate;
    
    public ShipmentStatisticsDao(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    
    // 복잡한 통계 (SQL 직접)
    public List<MonthlyStat> monthlyStats() {
        String sql = """
            SELECT YEAR(created_at) as y, MONTH(created_at) as m,
                   COUNT(*) as cnt, SUM(weight) as total_weight
            FROM shipments
            GROUP BY YEAR(created_at), MONTH(created_at)
            """;
        return jdbcTemplate.query(sql, (rs, n) -> 
            new MonthlyStat(rs.getInt("y"), rs.getInt("m"),
                            rs.getInt("cnt"), rs.getBigDecimal("total_weight")));
        // 반복 코드 없음 (JdbcTemplate)
        // SQL 은 직접 (MySQL 문법)
    }
}
record MonthlyStat(int year, int month, int count, java.math.BigDecimal weight) {}
class JdbcTemplate {
    <T> java.util.List<T> query(String sql, RowMapper<T> m) { return null; }
    interface RowMapper<T> { T mapRow(java.sql.ResultSet rs, int n) throws java.sql.SQLException; }
}

6.6 자기 점검 답변

JdbcTemplate은?

:
1. JdbcTemplate:

  • 반복 제거
  1. 동작:

    • 자원/예외 자동
  2. 사용:

    • SQL + RowMapper
  3. SQL:

    • 직접 (DB 차이 있음)

7️⃣ MyBatis

7.1 MyBatis

MyBatis:

  SQL Mapper:
    - SQL 을 XML 외부화
    - 객체 ↔ SQL 매핑
    - DB 별 분기 가능

7.2 XML SQL

<!-- MyBatis XML -->
<mapper namespace="ShipmentMapper">
  <select id="findById" resultType="Shipment">
    SELECT * FROM shipments WHERE id = #{id}
  </select>
</mapper>

7.3 DB 별 분기

<!-- DB 방언 분기 -->
<select id="page" resultType="Shipment">
  <if test="dbType == 'mysql'">
    SELECT * FROM shipments LIMIT #{size} OFFSET #{offset}
  </if>
  <if test="dbType == 'oracle'">
    SELECT * FROM (...) WHERE ROWNUM <= ...
  </if>
</select>

7.4 장점

MyBatis 장점:

  - SQL 외부화 (가독성)
  - SQL 직접 제어
  - DB 별 분기
  - 동적 SQL (if, foreach)

7.5 ILIC 의 맥락

<!-- MyBatis 예시 (ILIC 가 채택했다면) -->
<mapper namespace="com.ilic.dao.ShipmentMapper">
  <select id="findByStatus" resultType="Shipment">
    SELECT id, bl_no, status, weight
    FROM shipments
    WHERE status = #{status}
    <if test="orderBy != null">
      ORDER BY ${orderBy}
    </if>
  </select>
  
  <!-- DB 별 분기 -->
  <select id="page" resultType="Shipment" databaseId="mysql">
    SELECT * FROM shipments LIMIT #{size} OFFSET #{offset}
  </select>
  <select id="page" resultType="Shipment" databaseId="oracle">
    SELECT * FROM (
      SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM shipments ORDER BY id
      ) a WHERE ROWNUM <= #{max}
    ) WHERE rn > #{offset}
  </select>
</mapper>

<!-- ILIC: 주로 JPA, 일부 복잡 쿼리는 JdbcTemplate -->
<!-- MyBatis 는 SQL 제어 강한 프로젝트에 -->

7.6 자기 점검 답변

MyBatis는?

:
1. MyBatis:

  • SQL Mapper
  1. XML SQL:

    • SQL 외부화
  2. 분기:

    • DB 별 if
  3. 장점:

    • SQL 제어, 동적

8️⃣ JPA/Hibernate (Dialect)

8.1 JPA / Hibernate

JPA / Hibernate:

  ORM (Object-Relational Mapping):
    - 객체 ↔ 테이블 매핑
    - SQL 자동 생성
    - SQL 거의 안 봄

8.2 객체 중심

// JPA 엔티티
@Entity
@Table(name = "shipments")
public class Shipment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "bl_no")
    private String blNo;
    // ...
}

// 사용 (SQL 없이)
shipmentRepository.save(shipment);
Shipment found = shipmentRepository.findById(1L).orElseThrow();

8.3 Dialect (방언)

Dialect (방언):

  DB 별 SQL 차이 자동 처리:
    - MySQLDialect
    - OracleDialect
    - PostgreSQLDialect

  Hibernate 가:
    - 객체 호출 → Dialect 기반 SQL
    - DB 별 자동 변환

8.4 ORM 이 해결

ORM 이 해결:

  SQL 문법 차이:
    - Dialect 가 자동
    - 페이징/시퀀스 등
    - 자동 키 생성

→ "왜 ORM?" 의 답:
  JDBC 가 안 한 SQL 차이를
  ORM 이 해결

8.5 ILIC 의 맥락

// JPA (ILIC 주력)
@Entity
@Table(name = "shipments")
public class Shipment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    // MySQL: AUTO_INCREMENT, Oracle: SEQUENCE 자동
    private Long id;
    
    private String blNo;
    private BigDecimal weight;
    private String status;
}

// Repository (SQL 자동)
public interface ShipmentRepository extends JpaRepository<Shipment, Long> {
    // 메서드 이름 → SQL 자동
    List<Shipment> findByStatus(String status);
    Page<Shipment> findAll(Pageable pageable);   // 페이징 자동 (DB별)
}

// application.yml
// spring:
//   jpa:
//     properties:
//       hibernate:
//         dialect: org.hibernate.dialect.MySQLDialect
//     # Oracle 이면: OracleDialect

// → JPA 가 DB 차이 자동 처리
// → ILIC 가 102 테이블 관리 가능
// → 복잡 쿼리는 JdbcTemplate 보완
class Pageable {}
class Page<T> {}
interface JpaRepository<T, ID> {
    java.util.List<T> findAll();
}

8.6 자기 점검 답변

ORM이 SQL 차이 해결하는 방식 (Dialect) 은?

:
1. ORM:

  • 객체 ↔ 테이블
  1. Dialect:

    • DB 별 방언
  2. 자동:

    • SQL 생성
  3. 해결:

    • JDBC 가 안 한 SQL 차이

9️⃣ Phase 3 완주 정리

9.1 Phase 3 학습 종합

Phase 3 — JDBC 표준화

Unit 3.1 — JDBC 없던 시절의 고통
  - DB 고유 API, 재작성
  - OCP 위반

Unit 3.2 — JDBC의 표준화 효과
  - 자바 DB 표준 API
  - 같은 코드, 다른 DB

Unit 3.3 — JDBC가 해결하지 않는 것
  - SQL 문법 차이
  - 반복 코드
  - 상위 프레임워크

9.2 핵심 메시지

Phase 3 핵심 메시지:

  "JDBC 가 DB 접근 API 를 통일했지만
   SQL 문법 차이와 반복 코드는 남았고,
   이를 JdbcTemplate/MyBatis/JPA 같은
   상위 프레임워크가 해결했다."

9.3 다음 Phase 예고

Phase 3 → Phase 4:
  - JDBC → Connection Pool

Phase 4 — Connection Pool과 DB 세션 (4.2 ★깊이):
  - 매 요청 연결의 비효율
  - Connection Pool (★깊이)
  - DB 세션과 연결
  - DB Lock

9.4 면접 단골 질문 매핑

Q핵심 답변
JDBC 한계?SQL 차이/반복/매핑
LIMIT vs ROWNUM?페이징 문법 차이
자동 증가?AUTO_INCREMENT vs SEQUENCE
반복 코드?try/catch/finally
상위 프레임워크?JdbcTemplate/MyBatis/JPA
왜 ORM?SQL 차이 해결
Dialect?DB 방언
JdbcTemplate?반복 제거
MyBatis?SQL 외부화
JPA?객체-테이블 매핑

9.5 추가 심화 질문

Q1: ORM 의 단점?

답:

  • 복잡 쿼리 어려움
  • 학습 곡선
  • N+1 문제
  • 성능 최적화 까다

Q2: 네이티브 쿼리?

답:

  • JPA 의 SQL 직접
  • @Query(nativeQuery = true)
  • DB 종속 (의도적)
  • 성능/복잡 쿼리

Q3: JdbcTemplate vs JPA?

답:

  • JdbcTemplate: SQL 직접, 단순/성능
  • JPA: 객체 중심, 생산성
  • 혼용 가능
  • 프로젝트 성격

Q4: Spring Data JDBC?

답:

  • JPA 보다 단순
  • JdbcTemplate 위
  • 객체 매핑
  • 가벼움

Q5: SQL 표준 (ANSI)?

답:

  • ANSI SQL: 표준
  • DB 별 확장 (방언)
  • 표준만 쓰면 이식성
  • 현실은 방언 사용

🎯 핵심 요약 — 3줄 정리

1. JDBC 의 한계

  • API 는 통일했지만 SQL 문법 차이 (LIMIT vs ROWNUM 등) 그대로
  • 반복 코드 (try/catch/finally) + 매핑 부담

2. 상위 프레임워크

  • JdbcTemplate (반복 제거, SQL 직접)
  • MyBatis (SQL 외부화 + 분기)
  • JPA/Hibernate (Dialect 로 SQL 자동)

3. "왜 ORM"의 답

  • JDBC 가 안 한 SQL 차이를 ORM 의 Dialect 가 해결
  • ILIC 는 JPA 주력 + 복잡 쿼리는 JdbcTemplate

🏆 Phase 3 완주 — JDBC 표준화의 등장

💾 Phase 3 — JDBC 표준화의 등장
  ✅ Unit 3.1 JDBC 없던 시절의 고통
  ✅ Unit 3.2 JDBC의 표준화 효과
  ✅ Unit 3.3 JDBC가 해결하지 않는 것 ← 여기, Phase 3 완주

→ JDBC 전 (구체 강결합, OCP 위반)
→ JDBC (표준 API, 5주차 패턴)
→ JDBC 한계 + 상위 프레임워크

📚 다음으로...

Phase 4 — Connection Pool과 DB 세션 (4.2 ★깊이)

💾 Phase 4 — Connection Pool과 DB 세션
  Unit 4.1 — 매 요청마다 연결의 비효율
  Unit 4.2 — Connection Pool 개념 ★깊이
  Unit 4.3 — DB 세션과 연결 구조
  Unit 4.4 — DB Lock 개념

6주차 누적 진행

🧪 Part A (9 Unit) ✅
💾 Part B — DB 접근의 진화
  ✅ Phase 3 — JDBC (3 Unit) ← 완주
  ⏭ Phase 4 — Connection Pool (4 Unit, 4.2 ★깊이)

총: 12/28 Unit

🏆 Phase 3 완주 — JDBC 의 한계와 상위 프레임워크

profile
Software Developer

0개의 댓글