JDBC와 JPA

Eunkyung·2022년 1월 16일
0

JPA

목록 보기
1/1

상황에 따라 적절한 기술을 사용하기 위해서는 기술에 대한 이해뿐만 아니라 동작 원리에 대한 이해가 필요하다고 생각한다. JPA를 공부하면서 JDBC와 어떤 차이점이 있는지 궁금했고 공부한 내용을 정리해보았다.

먼저, JDBC와 JPA를 이해하기 위해서는 영속성(Persistence)에 대한 개념이 필요하다.

영속성(Persistence)

영속성이란, 프로그램이 종료되더라도 사라지지 않는 데이터의 특성을 말한다.
"스프링 입문"이라는 김영한님 강의를 들었을 때 DB 연결 전, Map에 데이터를 저장하였다. Map에 데이터를 저장했다는 것은 영속성을 갖지 않는 데이터와 같은 의미로 메모리에서만 존재하기 때문에 프로그램을 종료하면 데이터가 날아갔었다.
이 때, 프로그램 종료 후에도 영구적으로 데이터를 저장하기 위해 영속성이라는 개념이 등장하게 된다.

Persistence layer는 프로그램 아키텍처에서 데이터에 영속성을 부여해주는 계층을 말하는데, Persistence framework를 주로 이용한다.
Persistence framework는 JDBC 프로그래밍의 복잡함이나 번거로움없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있고 안정적인 구동을 보장한다. Persistence framework는 크게 SQL Mapper와 ORM으로 나눌 수 있다.

SQL Mapper

SQL Mapper는 SQL query문을 통해 직접 데이터베이스 데이터를 다루는 것으로 Mybatis와 JdbcTemplate이 있다.

ORM

ORM은 데이터베이스 객체를 자바 객체로 매핑함으로써 객체 간의 관계를 바탕으로 SQL을 자동으로 생성해준다. 즉, SQL query문을 작성할 필요가 없으며 객체 중심 개발이 가능하다.

이제 본격적으로 JDBC와 JPA에 대해서 알아보자.

JDBC

JDBC는 DB에 접근할 수 있도록 Java에서 제공하는 API로 Plain JDBC와 Spring JDBC가 있다.
Spring JDBC 접근 방법 중 하나로 많이 사용되는 JdbcTemplate은 내부적으로 Plain JDBC API를 사용하지만 다음과 같은 문제점이 있어 JdbcTemplate을 사용할 경우 핵심 로직에 집중할 수 있다는 장점이 있다.

그렇다면 Plain JDBC를 사용하면 어떤 문제점이 있을까?

  1. 쿼리 실행 전과 후에 많은 코드를 작성해야 한다.
  2. 데이터베이스 로직에서 예외 처리 코드를 수행해야 한다.
  3. 트랜잭션을 처리해야 한다.
  4. 이러한 모든 코드를 반복하기 때문에 비효율적이다.
 public Optional<Member> findByName(String name) {
        String sql = "select * from member where name = ?";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, name);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                Member member = new Member();
                member.setId(rs.getLong("id"));
                member.setName(rs.getString("name"));
                return Optional.of(member);
            }
            return Optional.empty();
        } catch (Exception e) {
            throw new IllegalStateException(e);
        } finally {
            close(conn, pstmt, rs);
        }
    }

딱 보기에도 길어진 코드에 현기증이 난다. 그렇다면 JdbcTemplate을 사용하면 어떻게 달라질까?

private final JdbcTemplate jdbcTemplate;

  public MemberRepository(DataSource dataSource) {
      jdbcTemplate = new JdbcTemplate();
  }
  
  public Optional<Member> findByName(String name) {
      List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
      return result.stream().findAny();
  }

Spring JDBC가 Connection 열고 닫기, 예외 처리와 트랜잭션 처리를 해주기 때문에 개발자는 datasource 설정, SQL 작성, 결과 처리 수행에만 집중할 수 있어 Plan JDBC에 비해 코드가 훨씬 간결해진 것을 확인할 수 있다.

코드가 간결해졌음에도 불구하고 SQL query문을 작성해야 하기 때문에 객체 지향 개발이 어렵다는 단점이 있다. 이를 해결하기 위해 JPA가 등장하게 된다.

JPA

JPA는 자바 ORM 기술에 대한 표준 명세로 Java에서 제공하는 API이다. 즉, ORM을 사용하기 위한 표준 인터페이스를 모아둔 것으로 대표적인 구현체로는 Hibernate가 있다.
EntityManager를 통해 엔티티를 영속성 컨텍스트에 저장하고 객체와 테이블을 매핑하여 객체 지향 개발이 가능하다는 특징이 있다.

public Optional<Member> findByName(String name) { 
        List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class) // JPQL : 객체를 대상으로 쿼리 날리면 sql로 번역
                .setParameter("name", name)
                .getResultList();
        return result.stream().findAny();
    }

JPA를 사용할 경우 많은 장점이 있지만 어렵고 제대로 사용하지 않을 경우 데이터 손실이 있다는 단점이 있다.

현재 JPA를 공부하고 있는데 신기한 기술이면서도 알면 알수록 어려운 것 같다.

Reference
profile
꾸준히 하자

0개의 댓글