JPA !!!!

매니·2022년 9월 16일
0

JPA

목록 보기
1/2
post-thumbnail

Mybatis 만 사용했던 사람의 JPA 기록기!

저는 Spring를 이용하여 프로젝트를 할때 Mybatis 만을 사용해서 진행하였고, 최근에 JPA에 대한 신세계를 알게되어서 요리조리 프로젝트의 Mybatis와 비교해가면서 JPA에 대해서 설명해보고자 합니다!!

기존의 SQL 문제점

자바 스프링으로 SQL을 작성할때면 Mybatis 를 이용해서 SQL문을 작성했을 테고 SQL문을 반복해서 작성했을 것 입니다.

INSERT INTO...
UPDATE ..
SELECT ..
DELETE ..

이런식으로요.

public class Member {
	private String memberId;
    private String name;
}
INSERT INTO MEMBER(member_id, name) VALES (memberId, name)
SELECT member_id, name FROM MEMBER

이런식으로 코드를 짜서 insert 해주거나 select 해주곤 했습니다.

그렇다면 여기서 member 에 joinDate 를 추가하고 싶습니다. 그렇다면...?

public class Member {
	private String memberId;
    private String name;
    private Date joinDate;
}
INSERT INTO MEMBER(member_id, name, joinDate) VALES (memberId, name, joinDate)
SELECT member_id, name, joinDate FROM MEMBER

한두개의 SQL문이라면 일일히 수정할 수 있겠지만 이것이 수십개, 수백개가 된다면 어떻게 수정할 수 있을까요?

사람이 코딩하는 것이기때문에 자잘한 실수는 나올테고 오류는 정말 많이 나올 것 입니다.

여러개의 테이블을 JOIN하는 SQL문 같은 경우는 상상이상일테고요.

또다른 문제점은 엔티티의 신뢰 문제입니다.

현업에서는 혼자 코딩하는 것이 아니고 여러사람이 함께 코딩을 합니다. 그렇다면 추가된 joinDate 가 SQL문에 추가가 되어있는지, 조회되고 있는지 어떻게 신뢰할까요?

코드를 전부다 확인해가면서 joinDate 가 있는지 없는지 확인해야 할 겁니다.

그렇다면 객체지향적인 관점에서 봤을때 이는 심각하게 훼손되는 상황일겁니다.

그래서 나온것이 JPA 입니다.

JPA는 자바진형의 ORM 기술의 표준입니다. 그렇다면 ORM부터 알아봅시다.

ORM

ORM 이란

  • Object-relational mapping(객체 관계 매핑)
  • 객체는 객체대로 설계
  • 관계형 데이터베이스는 관계형 데이터베이스대로 설계
  • ORM 프레임워크가 중간에서 매핑해준다.

한마디로 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑시겨주는것을 말합니다.

ORM의 장점

  • 객체지향적인 코드를 통해서 코딩에 좀 더 집중할 수 있도록 해줍니다.

한마디로 자동으로 매핑시켜주기때문에 개발자는 INSERT INTO.. UPDATE.. 이런 SQL문을 반복적으로 코딩할 일이 없다는 겁니다.

  • 재사용 및 유지보수의 편리성이 증가합니다.

당연합니다 위에서의 joinDate 를 추가하면 모든 SQL문에 추가를 해줘야하는데 ORM의 기술중 하나인 JPA를 사용하면 자동으로 joinDate 를 추가해주기 때문에 재사용과 유지보수가 편리합니다.

그렇다면 단점은 무엇이 있을까요,

ORM의 단점

  • 완벽한 ORM으로만 서비스를 구현하기 어렵다.

이것은 완벽하게 설계가 되어있어야 사용하기 편리하다는 말입니다.

동작원리를 정확히 알고 설계가 되어있어야 사용할 수 있습니다.

JPA

  • Java Persistence API
  • 자바 진영의 ORM 기술 표준

대부분의 객체지향언어는 ORM 기술을 갖고있고 자바진영에서는 그것이 JPA인 것 입니다.

JPA는 독립적으로 작용하는 것이 아니라 JDBC 사이에서 동작합니다.

JPA의 동작순서를 간단히 얘기해보자면,

  1. Member 쪽에서 Entity Object를 받아옵니다.
  2. JPA는 이를 분석하고 스스로 SQL문을 생성합니다.
  3. 그뒤에 JDBC API를 사용하고 DB에 데이터를 넣고, 수정하고, 삭제할 수 있는겁니다.

그렇다면, JPA를 왜 사용해야 되는 걸까요?

JPA의 장점

  • SQL 중심적인 개발에서 객체 중심으로 개발이 가능합니다.
  • 생산성과 유지보수가 뛰어납니다.
  • 성능면에서 뛰어납니다.
  • 트랜잭션을 지원합니다.

우선, 생산성에대해서 얘기해보자면 JPA를 사용한다면 고작 코드 1줄로 DB에 저장할 수 있습니다.

jpa.persist(member)

기존의 Mybatis 는 SQL문을 길게 써야되었음에도 jpa는 한줄로 DB에 저장이 가능합니다.

JPA 코드

Member 코드입니다.

@Entity
public class Member {

    @Id
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

lombok를 사용했다면 좀 더 편리했을텐데, 재쳐주고 우선 Member 를 생성해줍니다.

  1. 등록
public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
       
        // 데이터 등록
        try {
            Member member = new Member();

            member.setId(2L);
            member.setName("HelloB");

            em.persist(member);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }
       
   }
        
  1. 조회하기
public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        
        try {

            Member findMember = em.find(Member.class, 1L); // 조회하기
            System.out.println("findMember.id = " + findMember.getId());
            System.out.println("findMember.name = " + findMember.getName());

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();

    }
}
        
  1. 삭제하기
public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        
        try {

            Member findMember = em.find(Member.class, 1L); // 조회하기
            em.remove(findMember); // 삭제하기
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();

    }
}
        
  1. 수정하기
public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        
        try {

            Member findMember = em.find(Member.class, 1L); // 조회하기
            findMember.setName("HelloJPA"); // 수정하기
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();

    }
}
        

아래는 실제로 요리조리에서 쓰였던 코드입니다.

요리조리 mybatis recipeMepper

<insert id="insertRecipe" parameterType="com.sp.yorizori.recipe.Recipe">
		INSERT INTO recipe (recipeNum, caseNum, countryNum, recipeSubject, recipeHitcount, 
			recipeReg_date, 
			recipeServing, recipeLevel, 
			recipeContent, recipeTime,userId, active) VALUES 
   		(#{recipeNum}, #{caseNum}, #{countryNum}, #{recipeSubject}, 0, SYSDATE, 
   		#{recipeServing}, #{recipeLevel}, #{recipeContent}, #{recipeTime}, #{userId}, 0)
</insert>

한눈에 봐도 복잡해보입니다. 여러테이블을 JOIN해줘야하는 것은 물론, 여기서 추가해주려고하면 모든 쿼리문들을 수정해줘야합니다.

JPA에 대해서 짧게나마 알아보았습니다. 앞으로 더 세세하게 알아볼것이고 JPA를 이용하여 프로젝트도 진행해볼 예정입니다.


💡 I Learned

우선 첫번째로는 JPA의 존재와 JPA의 편리성에 대해서 배웠다. 요리조리 프로젝트 당시, 얼마나 많은 insert 문과 update, select, delete 문을 코딩하였고, 단 하나의 값을 넣어주지 않았다는 이유로 nullpoint 를 얼마나 많이 보았는지,

JPA에 대해서 알아가면 알아갈수록 신세계였다.

그리고 요리조리 프로젝트가 얼마나 엉망진창이었는지 알게되었다.

이 프로젝트를 가지고 취업준비를 해도되는걸까 싶었지만 그래도!!!

과거의 나는 반성하고 오늘의 나는 알아가고 내일의 나는 발전한다!!

JPA에 대해서는 꾸준히 포스팅 할 예정이고 함께 알아가셨으면 좋겠습니다!

profile
성장중 🔥

0개의 댓글