오늘은 JPA(Java persistence API)에 대해 공부 했다. 모든 어플리케이션은 DB를 사용한다. 하지만 JPA를 사용했을 땐 기존의 방식과 너무 달라서 신선했다. 기존의 방식은 DB를 연결하기 위해 코드를 수십줄씩 작성했어야 했고 이것저것 복잡했다.
하지만! JPA는 너무나 간단 그 자체였다.
apllication.properties에
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/
spring.datasource.username=root
spring.datasource.password=******
datasource에 관한 정보만 적어주고
public interface MemberRepository extends JpaRepository<Member, Long> {
}
JpaRepository를 상속한 인터페이스 선언 하나면 정말 끝이다.
처음에 쓰면서 이게 맞나 싶고 이게 대체 무슨 구조로 되어 있길래 단순히 인터페이스 선언 하나만 해도 DB와 연동이 된다는게 도대체 이해가 되질 않았다.
분명히 DB와 데이터를 주고 받기 위해서는 쿼리문을 작성해야 하는데 쿼리문 작성을 한번도 안했는데 이게 된다고?
그래서 오늘은 JPA의 구조와 특징에 대해 제대로 알아보기 위해 공부한다.
일단 JPA를 하기 전에는 ORM이 무엇인지부터 알아야한다.
ORM은 Object-relational mapping의 약자로 객체관계매핑의 뜻을 가진다. 기존의 방식에는 DB에서 데이터를 조회해서 가져오면 객체와 Mapping해주는 작업이 항상 바늘가는데 실가듯 뒤따랐다. 하지만 ORM 프레임워크가 이걸 다 해준다.
JPA는 인터페이스일 뿐 실제로 구현된것이 아니다. 필자는 구현체로 hibernate를 사용한다.
위 그림과 같이 EclipseLink, DataNucleus같은 또 다른 구현체도 존재한다.
JPA는 애플리케이션과 JDBC 사이에서 동작을 한다.
JPA를 사용하면 JPA 내부에서 JDBC API를 사용하여 SQL을 호출하고 DB와 통신하는 구조이다. 이러한 구조때문에 위에 필자가 말한 쿼리문을 직접 사용하지 않아도 DB와 통신이 가능한 것이다.
개발자가 해야 하는 행동
1. JPA에 Entity를 넘긴다.
JPA가 하는 행동
1. Entity 분석
2. INSERT SQL 생성
3. JDBC API를 사용해 SQL을 DB에 보냄
원래는 모두 개발자가 해야하는 것들 이었지만 JPA가 무려 절반이상을 대신해준다!
나의 비서가 생긴 느낌이랄까..ㅎㅎ
1. SQL중심이 아니라 객체지향중심의 개발이 가능하다.
기존에는 자바 객체를 SQL로, SQL을 자바 객체로 변환하는 과정의 무한반복이었다. 따라서 굉장히 지루한 작업을 반복적으로 해야하는 문제가 있었다.
public interface BoardRepository extends JpaRepository<Board, Long> {
Optional<List<Board>> findByMemberOrderByCreatedDateDesc(Long id); //이름으로 검색할 때 사용하기 위한 함수(내림차순)
Optional<List<Board>> findByTitleOrderByCreatedDateDesc(String title); //제목으로 검색할 때 사용하기 위한 함수(내림차순)
Optional<List<Board>> findByMember_NickName(String nickName);
Optional<List<Board>> findByMember_Id(Long id);
Optional<List<Board>> findByType(BoardType boardType);
}
하지만 JPA는 Repository를 interface로 선언하고 JPARepository를 상속하면 SQL문 생성부터 Mapping까지 자동으로 해준다. 심지어 SQL문도 메서드형으로 자동으로 생성해서 가져오므로 반복적인 SQL문 작성을 하지 않음으로써 코드량이 상당히 줄어든다.
2. 생산성이 높다.
1번에 적은 내용과 상당수 비슷한 내용이다. 반복적인 작업을 없애면서 상댱량의 코드가 줄어들고 그로인해 SQL문 만드는것에 더 적은 시간을 할애해도 되기 때문에 다른 곳에 더 많은 시간을 투자할 수 있다는 장점이 있다.
3. 유지보수가 굉장이 용이하다.
기존에는 필드 변경 시 모든 SQL을 수정해야 하지만 JPA는 필드만 추가하면 SQL문은 JPA가 알아서 처리하기 때문에 간단히 해결할 수 있다.
4. Object와 RDB간의 패러다임 불일치가 해결된다.
연관관계를 맺을 때 객체는 참조를 활용하고, 테이블은 외래키를 이용한다. 객체와 테이블은 서로 지향하는 목적이 다르기 때문에 패러다임이 불일치하는 현상이 일어나는 것이다.
따라서 기존의 방식으로는 객체 지향적으로 설계를 하면 할수록 패러다임의 불일치가 더욱 심화되는 양상이었다. 하지만 JPA를 이용하면서 이러한 불일치가 감소하여 객체지향적으로 설계가 가능해졌다.
5. 성능을 최적화 하는데 도움이 된다.
JPA는 캐싱기능이 있다.
Long member_id = 1L;
Member member1 = memberRepository.findById(member_id); // 1번
Member member2 = memberRepository.findById(member_id); // 2번
println(member1 == member2) // 3번
캐싱기능이 무엇인가 하면 1번에서 memberRepository를 호출하면 SQL문이 생성되어 DB로 보내지는 과정이 이루어지고 캐시에 저장이된다.
같은 Transaction 안에 있는 2번은 memberRepository를 호출하면 SQL문이 생성되지 않고 캐시에 저장된 Entity를 호출한다. JAVA에서 DB를 호출하는 과정이 생각보다 많은 리소스를 차지하는데 쓸데없는 SQL문을 생성하지 않음으로써 리소스낭비를 줄일 수 있다.
JPA를 사용했을 때 좋은점을 나열하면서 JPA가 무엇인지에 대해 공부를 하였다. 다음 시간에는 JPA를 활용해서 진행하고 있는 프로젝트를 적으면서 추가적인 공부를 해봐야겠다.