Spring

Spring의 JDBC, SQLMAPPER, ORM

Hoonco 2022. 5. 12. 02:55

JDBC API

- Java DataBase Connectivity

- 자바에서 직접 지원하는 Database 연결 표준 인터페이스이다.

 

Java Application 밑에 JDBC API가 있으며 

API 관리하에 JDBC Driver Manager가 움직이며 DB와의 Connection을 연결, 관리 해준다.

DB 제품에 따라 SQL문이 조금씩 달라지거나 조건이 상이하기 때문에 이를 JDBC Driver가 해결해준다.

즉 JDBC Driver만 사용하는 DB에 맞춰준다면 어떤 제품의 DB이던 사용이 가능하다

 

JDBC의 기본 동작 원리

 

① Driver Manager가 Conneciton 인스턴스를 제공한다

② Connection을 통해서 Statement를 얻고

③ Statement를 통해 ResultSet을 얻는 방식이다.

※ Statement는 명령문이라는 뜻으로 즉 SQL 문 같은 명령문을 뜻한다.

 

하지만 이 JDBC는 단점이 많았는데

1. Connection을 직접적으로 관리해줘야 하며

2. SQL문을 일일히 작성해주어야 한다.

 

이 단점을 보완하고자 개발이 된것이 SQLMAPPER 이다.

 

현재 SQL Mapper는 크게 Spring JDBC와 MyBatis로 나뉜다

 

Spring JDBC

 

Spring JDBC는 Configuration for Connection 이라고 해서 DatatSource의 설정을 통해 커넥션을 보다 쉽게 

이용할 수 있는 Template 형식의 라이브러리이다.

 

public class DAO {

    private JdbcTemplate jdbcTemplate;

    public DAO(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public List<Account> getAccount() {
        return jdbcTemplate.query("select * from account", new RowMapper<Account>() {

            @Override
            public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
                return new Account(rs.getInt("id"), rs.getString("name"));
            }
        });
    }
}

Spring JDBC의 사용 예이다.

 

Spring JDBC는 개발자들을 편하게 해주었다.

연결, statement 준비와 실행, 반복 루프, 예외 처리, 트랜잭션 제어, connction 닫기 등을 사용 해주는 등

여러 이점을 가져왔다.

 

MyBatis

MyBatis는 Spring JDBC와 같은 SQL Mapper이지만 다르게 구성되어 있다.

MyBatis는 자바 코드와 SQL을 아예 분리 하는 목적을 갖고 있었다.

 

MyBatis는 Query를 Java 파일이 아닌 별도의 XML 파일로 구성하여 제공하였다. ( 기본적으로 mapper.xml )

 

Entity의 interface와 추상 메소드를 만들고 MyBatis가 xml과 interface를 읽어 SQL 문을 자동으로 가져 온다.

 

 

하지만 이런 SQL Mapper도 단점이 있다 바로

OOP 방식과 너무나도 맞지 않다는 것이다.

예를 들면 Meber와 Team이 있다고 하면 이는 객체 지향적으로 표현은 되지만 DB에서는 표현 하지 못한다

( Team이 아니라 Team의 id 값이 필요하다 )

이런 패러다임의 차이 때문에 유지보수 측면에서 매우 떨어지는 현상이 자주 발생하였다.

 

이러한 패러다임의 불일치를 최소화하고자 나온 것이 ORM이다.

 

ORM

 

Java에서 가장 많이 쓰이는 ORM은 JPA, Hibernate가 있다

JPA와 Hibernate는 같이 쓰인다.

JPA가 ORM을 interface로 만든 것이며 이를 구현한 라이브러리가 Hibernate인 것이다.

즉 Hibernate는 여러 구현체중 하나이며 EclipseLink, DataNucleus 등이 존재한다.

( JPA에서는 표준적으로 Hibernate를 사용 )

 

Java ORM인 JPA에선 가장 중요한 핵심 두 가지가 있는데

EntityManager와 영속성 컨텍스트다 

 

EntityManager가 DB에서 entity를 들고 오면 entity에 persist 즉 영속성을 걸어주고

EntityManager가 해당 entity를 지속적으로 관리, 감독한다.

예를들어 EntityManager가 entity를 들고왔고 이에 대한 수정 사항이 생기면 EntityManger가 수정 사항을 감지하여

DataBase에 flush, 즉 신호를 보낸다. 이를 더티 체킹 (Dirty Checking)이라고 한다.

 

하지만 이러한 편한 ORM 마저 단점이 존재한다.

가장 큰 문제점은 n+1 문제이다.

의도한 것은 컬럼 하나만 조회하기 위함이었는데 모든 컬럼이 조회되는것은 물론 연관관계가 정의 되어 있는 entity들이 모두 한꺼번에 조회가 되는 것이다.

이는 매우 큰 성능저하를 가져올 수 있는 문제이다 SQL문이 퍼지면서 최소 2배 많으면 10배, 100배에 다르는 쿼리문이 날아간다 

 

이를 해결하기 위해 EntityManager는 Lazy Loading을 지원한다.

Lazy Loading은 연관관계가 걸려있는 항목들은 프록시(Proxy) 엔티티, 즉 가짜 객체를 불러와놓고

실제 코드에서 해당 연관관계가 걸려있는 것을 가져올 때 쿼리문이 나가는 기술이다.

 

또한 캐시 기능도 지원하지만 실질적으로 큰 효율은 발휘하지 못한다고 한다.

 

여기서 한 술 더떠서 만들어진게 Spring Data JPA이다.

 

Spring Data JPA는 interface와 추상 메소드를 이용하여 

JpaRepository를 상속한것 만으로

save, findBy, delete 등 여러 기능을 제공하여 매우 단순하고 쉽게 DB에 접근 하도록 가능하게 해준다.

필자 또한 SQL과 DB에 관련해서 지식이 전무 했을때 이 Spring Data JPA를 이용해서 간단한 블로그 등을 만들었는데

정말 DB에 대해서 아무런 지식이 없음에도 불구하고 쉽게 만들 수 있도록 되어있었다. ( 스프링 짱..! )

Spring Data JPA의 구현체를 직접 들어가보면 EntityManager가 있는것을 볼 수 있다.

 

아래 그림은 Spring Data JPA가 동작하는 방식이다.

Spring Data JPA, JPA, Hibernate, JDBC의 논리 구조

 

 

마치며

 

스프링을 한지 1년이 지났지만.

Spring Data JPA가 너무 편리하고 좋았던 탓에 해당 밑 기술에 대한 관심이 저조했다.

이번 글을 작성함을 통해 Spring Data JPA의 기반이 어떤것이고 어떻게 나오게 된 기술인지를 알게 된것 같다.

앞으론 항상 새로운 기술을 배울땐 꼭 해당 기술의 탄생 배경, 원리 정도는 파악하고 개발하면 용이 할 것 같다.