ORM(Object-Relational Mapping)은 객체 지향 프로그래밍 언어에서 사용하는 객체와 관계형 데이터베이스의 테이블을 매핑해주는 기술입니다. 쉽게 말하면, 자바 같은 언어에서 클래스를 정의하고 나면, 그 클래스와 DB 테이블이 자동으로 연결돼서 SQL문을 직접 작성하지 않고도 DB 조작이 가능해지는 방식을 말합니다.
Java Persistence API로 자바 ORM기술에 대한 API표준 명세이다. ORM을 사용하기 위한 인터페이스를 모아둔 것이다. 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스다. "인터페이스"이기 때문에 JPA를 사용하기 위해서는 JPA를 구현한 Hibernate, EclipseLink, DataNucleus와 같은 ORM 프레임워크를 사용해야 한다.
ex) Java에서 JPA를 사용해서 User라는 엔티티 클래스만 만들면 곧바로 user 테이블과 매핑되고, SQL문 없이 userRepository.findById() 같은 코드로 바로 데이터를 조회할 수 있습니다.
객체 지향 언어(Java, Python 등)를 쓰는 개발자 입장에서는, 매번 SELECT, INSERT 같은 SQL을 직접 짜지 않아도 되니까 편합니다. 그 대신, 클래스와 속성 중심으로 생각하면서 데이터를 다룰 수 있어서 비즈니스 로직에 더 집중할 수 있습니다.
ORM(JPA, Hibernate, SQLAlchemy 등)을 사용할 때, 1번의 쿼리로 해결할 수 있는 작업이 N+1번의 쿼리로 실행되는 비효율적인 상황을 말합니다.
- 팀(team)와 선수(player)은 1:N 관계
- 즉, 하나의 팀에 여러 명의 선수들이 있습니다.
List<Team> teamList = teamRepository.findAll(); // 쿼리 1번 for (Team team : teamList) { List<Player> playerList = team.getPlayerList(); // 팀마다 쿼리 실행 (N번) }
- findAll() → 모든 팀 가져오는 쿼리 1번
- 각 부서의 getPlayerList() → 팀 수(N)만큼 쿼리
→ 즉, 총 N+1번의 쿼리가 실행됩니다.문제인 이유
1. 데이터가 많아지면 쿼리 수도 기하급수적으로 증가 2. 성능 저하, DB 부하 증가 3. 불필요한 네트워크 비용해결 방법
@Query("SELECT t FROM Team t JOIN FETCH t.players") List<Team> findAllWithPlayers();
메서드 호출로 쿼리를 실행한다는 것은 내부적으로 많은 동작이 있다는 것을 의미하므로, 직접 SQL을 호출하는 것보다 성능이 떨어질 수 있습니다. 실제로 초기의 ORM은 쿼리가 제대로 수행되지 않았고, 성능도 좋지 못했다고 합니다.
(그러나 지금은 많이 발전하여, 좋은 성능을 보여주고 있고 계속 발전하고 있습니다.)
public interface UserRepository extends JpaRepository<User, String> {
@Query(value = "select user " +
"from User user " +
"where user.name = :name")
List<User> findByName(@Param("name") String name);
}
ORM은 생산성, 유지보수, 객체지향 프로그래밍에 편리함을 주지만,
복잡하거나 최적화가 필요한 쿼리에서는 성능이 떨어질 수 있습니다.
반대로 직접 SQL을 쓰면 더 세밀하게 쿼리를 최적화할 수 있지만,
코드가 복잡해지고 유지보수가 어려워질 수 있습니다.
나의 생각은 sql의 작동원리 까지는 몰라도 기본적인 개념과 사용방법은 완벽히 다 알고 있어야 된다고 생각한다. 왜냐하면 현대의 웹 & 앱플리케이션에서 DB에 대한 접근이 필수적이기 때문에 그 도구인 SQL을 잘 모른다면 데이터에 대한 관리를 제대로 할 수 없기 때문에 그 웹 & 앱플리케이션 서비스를 이용하기 위험해지기 때문이다.
다양한 이유가 있겠지만 지금처럼 AI가 거의 다 해주는 세상에서 조금이라도 경쟁력이 있을려면 알고 있어야 한다고 생각한다.
https://f-lab.kr/insight/understanding-orm
https://dev-coco.tistory.com/73
https://ccomccomhan.tistory.com/131
https://velog.io/@xogml951/JPA-N1-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-%EC%B4%9D%EC%A0%95%EB%A6%AC
https://victorydntmd.tistory.com/195
https://velog.io/@bo-ram-bo-ram/JPQL