CS/데이터베이스

[데이터베이스] SQL Mapper, ORM 정리 + MyBatis, JPA, Spring Data JPA, Hibernate

개발중인 감자 2023. 8. 30. 15:37

 

0. 영속성 (Persistence)

- 데이터들이 프로그램이 종료되어도 사라지지 않고 어떤 곳에 저장되는 개념

- 자바에서 이런 영속성을 지원해주는 도구가 JDBC

- 하지만, JDBC는 개발자가 SQL문을 직접 맵핑해야하는 번거로움이 있음.

- SQL Mapper, ORM은 개발자가 직접 맵핑하지 않도록 도와주는 Persistence Framework

- Persistence Framework : 데이터베이스와의 연동되는 시스템을 빠르게 개발하고 안정적인 구동을 보장해주는 프레임워크

 

1. SQL Mapper

- 객체 (Object)와 SQL를 Mapping하여 데이터를 객체화하는 기술.

- DB마다 SQL문이 다르므로 DBMS에 종속적임. 

- 종류 : MyBatis

 

2. ORM (Object-relational Mapping)

- Object와 테이블을 Mapping해주는 기술.

- SQL 문이 아닌 관계형데이터베이스의 데이터에 직접 맵핑하기 때문에 SQL문을 작성할 필요가 없음. 

- 해당 데이터베이스 객체와 직접 맵핑하기 때문에 필요한 SQL문을 알아서 만들어줌.

- 그래서 DBMS에 종속적이지 않음. 그래서 개발자는 비즈니스 로직에 집중할 수 있음. 

- 또한 유지보수 및 재사용이 용이함. 

- 종류 : JPA

 

 


 

3. SQL Mapper - MyBatis

- 쿼리 기반 웹 애플리케이션을 개발할 때 가장 많이 사용되는 SQL Mapper 프레임워크.

- SQL 문을 XML 파일에 작성하기 때문에, SQL의 변환이 자유로움. 

- 우리나라의 시장은 대부분이 SI 또는 금융이기 때문에 비지니스가 매우 복잡하고,  안정성과 속도를 중요시하기 때문에 SQL문을 직접 작성하는 Mybatis을 많이 사용함.

 

<장점>

- JDBC를 직접 이용할 경우, 개발자가 반복적으로 작성해야할 코드가 많고, 서비스 로직 코드와 쿼리 분리가 어려움.

- 또한 커넥션 풀의 설정 등 개발자가 신경써야할 부분이 많다.

- 하지만 마이바티스는 JDBC를 통한 작업을 캡슐화하고, 일반 SQL 쿼리, 저장 프로 시저 및 고급 매핑을 지원하여 JDBC의 코드, 매개변수의 중복작업을 제거해줌.

- Java, C 등 어떤 프로그래밍 언어든 사용이 가능. 

 

<단점>

- SQL을 개발자가 직접 작성해야함.

- 테이블이 변경되고 DTO가 변경될 때마다 매핑에 대한 부분을 다시 수정해야하는 번거로움이 존재.

- 위와 같은 이유로 어플리케이션과 데이터베이스간의 설계에 대한 부분을 수정해야하는 경우 많은 설정이 바뀌어야 한다.

- 런타임을 해야 오류를 확인할 수 있다.

 


4. ORM - JPA

- 자바 ORM 기술에 대한 API 표준 명세서로, 자바에서 제공하는 API.
- 즉, ORM을 사용하기 위한 표준 인터페이스를 모아둔 것

- 특정 기능을 하는 라이브러리가 아닌 인터페이스

- EntityManager를 통해 영속성 관리.

💡 EntityManager란, 영속성콘텍스트를 관리하며, 이는 특정 영속성 콘텍스트가 관리하는 Entity 인스턴스의 집합이다.
영속성 콘텍스트은 데이터를 영구 저장하는 환경이다. @Entity 어노테이션을 달고 있는 Entity 객체들을 관리하며 실제 DB 테이블과 매핑하여 데이터의 CRUD하는 중요한 기능을 수행한다. 즉 EntityManager는 Entity 객체들을 영속성 콘텍스트에 보관하고 관리한다. 

- JPA를 구현한 라이브러리 : Hibernate

- JPA 기반으로 더 편리하게 사용가능한 라이브러리 : Spring Data JPA

 

5. Spring Data JPA

- Spring Data JPA는 JPA를 한 단계 더 추상화 한 인터페이스 제공.

- Spring framework에서 JPA를 편리하게 사용할 수 있도록 지원하는 라이브러리.

 

< JPA와 Spring Data JPA의 차이?>

- Spring Data JPA는 Repository 인터페이스를 제공하여 영속성을 관리하고 JPA는 EntityManager를 통해 영속성 관리.

- 즉 Spring Data JPA를 사용하면 Repository 인터페이스을 구현하여 JPA의 EntityManager 대신에 사용이 가능.

- Repository 인터페이스를 구현하면 기본적인 CRUD 작업이 가능.

  • Repository 개발시 인터페이스만 작성하면 Spring Data JPA가 메서드 이름을 분석해서 JPQL을 생성한다.(쿼리 메서드)
  • @Query 어노테이션을 사용하여 JPQL을 직접 작성한다.

코드 예시 - Spring Data JPA

더보기
@Entity
@Table(name = "user")
@Getter
@Builder
@NoArgsConstructor(force = true)
@AllArgsConstructor
public class User extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String email;
    private String name;
    private String pw;
}
public interface UserRepository extends JpaRepository <User, Long> {
	//DB와 데이터를 Mapping 해주는 repository 클래스
    // JpaRepository 의 조상 인터페이스에 Repository 인터페이스 존재.
    //기본적인 CRUD를 제공해주는 JpaRepository 상속받아 구현
}

JpaRepository <- PagingAndSortingRepository <- CrudRepository <- Repository(최상위)

CrudRepository 인터페이스에서 CRUD 할 수 있는 메소드 정의.

PagingAndSortingRepository 에서는 페이지와 소트에 관련된 메소드 정의. SQL문에서 order by 기능이 여기서 사용 가능.

//JpaRepository는 기본적인 CRUD를 제공하고 있으므로 우리는 다음과 같이 UserRepository의 save만 호출해주면 데이터가 저장된다. 
//그리고 findById를 이용하면 해당 객체를 꺼낼 수 있다.
@Service
@RequiredArgsConstructor
@Transactional(readonly = true)
public class UserService {

    private final UserRepository userRepository;

    @Transactional
    public User findUserAndUpdateName(Long id) {
        User user = userRepository.findById(id);
        user.setName("변경된 이름");
    }
}

 

<MyBatis 보다 장점>  - 출처 : https://mangkyu.tistory.com/20 

 

1) 엔티티에 맞는 테이블 생성 + DB 생성을 편리

- JPA는 설정에 따라 매핑된 객체를 바탕으로 테이블을 자동으로 만들어준다.

- 물론 자동 생성되는 이름이 가독성이 떨어져서 이대로 사용하기에는 부족하지만, 그래도 직접 모든 DDL을 작성하는 것보다는 편리함을 제공해준다.

 

2) 객체 지향 중심의 개발

- JPA는 객체를 이용하면 우리는 테이블에 매핑되는 클래스를 더욱 객체 지향적으로 개발할 수 있다.

- 그리고 이러한 방향은 객체 지향 언어인 Java에 더욱 잘 맞는다.

 

3) 테스트 작성이 용이

- JPA는 테이블을 자동으로 만들어주므로 테스트를 작성하기에 매우 좋다.

 

4) 기본적인 CRUD 자동화

- JPA는 테이블과 객체를 매핑시키는 기술이므로 기본적인 CRUD가 제공된다. 

 

5) 복잡한 쿼리는 QueryDSL을 사용해 처리

- MyBatis는 직접 SQL문을 작성하여 복잡한 쿼리를 작성할 수 있다. JPA에서는 QueryDSL 이라는 오픈소스를 사용한다면 문제를 해결할 수 있다. 아래의 코드는 QueryDSL을 이용한 예시이며 자바 언어로 매우 직관적인 쿼리를 작성할 수 있다는 장점이 있다.

 

코드 예시 - QueryDSL

더보기
@Repository
@RequiredArgsConstructor
public class QuizRepositoryImpl {

    private final JPAQueryFactory query;

    @Override
    public User search(final String email) {
        final QUser qUser = QUser.user;

        final User user = query.selectFrom(qUser)
                .where(qUser.email.equalsIgnoreCase(email))
                .fetch();
        return user;
    }
}

 

6. 하이버네이트(Hibernate)

- JPA 인터페이스를 구현한 라이브러리.

- JPA의 모든 기능을 지원하여 직접 SQL문을 작성할 필요 없음. 

- 그렇기 때문에 ORM의 장점인 유지보수에 용이.

 

 

 


출처 

- https://velog.io/@hyunjong96/JPA-JDBC-JPAHibernate-MyBatis

- https://velog.io/@rladuswl/ORM%EC%9D%98-%EA%B0%9C%EB%85%90-JPA%EC%99%80-MyBatis-%EC%B0%A8%EC%9D%B4 

- https://data-make.tistory.com/621

- https://mangkyu.tistory.com/20 

- https://lealea.tistory.com/238