JPA

Winsam·2024년 2월 29일
post-thumbnail

오늘 JPA에 대한 이론을 배웠다. 프로그래밍이라는게 그 시대에 유행하는 기법같은게 존재하는 듯한데 강사님 말씀으로는 요즘 유행하는 것은 myBatis 보다는 JPA인듯 하다. 그동안 myBatis를 통해서 SQL문을 스프링부트에서 어떻게 사용하는지에 대해서 배웠는데, JPA는 에너테이션(@) 을 이용해서 직접 xml으로 SQL문을 만들지 않고도 default로 정해진 SQL구문을 사용할 수 있다고 한다. 사실 코드들이 너무 생소해서 제대로 정리를 한번 더 하고싶어서 이곳에 JPA 이론을 정리해보겠다.

ORM (Object Relational Mapping)

Object Relational Mapping 라는 의미로 객체로 연결해준다는 의미이다. 미리 SQL문을 만들어놓고 그 SQL문을 필요할 때 불러서 쓰는 것인데, ORM의 기법들이 많아지니까 자바가 오히려 ORM에 종속되어버리는 상황에 놓이게 되었다. 수 많은 회사들이 ORM 개발에 뛰어들었고 수많은 ORM의 규칙에 맞춰서 자바코드를 만들어 버리게 되자 자바라는 코드의 장점이 사라지기 시작했다. 자바는 API를 통해 규칙성을 만들어서 운영체제별로 맞춘다거나 DB별로 맞춰야 하는 등의 노력이 필요없다. 자바 그 자체로 독립적인 언어인 점이 큰 장점인데, ORM에 종속이 되어버리니까 그 장점이 무너지는 상황이었다. 그래서 오라클 측에서 이에 대응해서 ORM에도 규칙을 만들었고, 그 규칙을 JPA라고 한다. (여기서 규칙은 인터페이스로 규칙을 만들었다는 의미이다.)

JPA (JAVA Persistence Api)

mySQL이 자바라는 프로그램 언어로 mySQL의 DB를 처리할 수 있도록 드라이버를 제공하고 있고 자바측에서 규칙(API)을 정해놓았다. 그 규칙을 JDBC드라이버관리자(JDBC API) 라고 한다.

그럼 자바측에서 mySQL이라는 DB와 접촉할 때 정해놓은 규칙의 방식으로 대표적으로 myBatis 방식과 JPA 방식이 존재하는데 MyBatis는 xml으로 DAO와 비슷한 SQL 구문을 만들어서 사용했지만, 사실 SQL 구문도 잘 들여다보면 규칙이 존재한다. 그 규칙을 활용해서 interface의 default 메서드를 활용해서 미리 SQL을 만들어놓고 필요할 때 해당 interface를 implements 해서 default 메서드를 호출해서 사용하자는 것이 JPA 의 핵심인 것 같다.

간단히 JPA를 이용해서 CRUD를 console에 찍어보기

딱히 코드를 만들거나 하진 않고 만들어진 코드를 설명하는 식으로 진행을 할 것이다. Spring Starter Project 를 하나 만들면서 'Spring Data JPA' 디펜던시를 추가하면서 만들겠다.

application.properties (설정파일)

스프링부트의 설정파일에서 JPA 설정을 해줘야 할 내용이 있다.

  1. 아래 코드는 '#'으로 주석처리를 했는데 존재하지않는 엔티티를 CRUD 같은걸 하려고하면 자동으로 새로운 엔티티를 생성해준다. 필요시에만 주석을 풀고 하는 것을 추천한다. (그냥 하다보면 어느순간 수많은 엔티티가 쌓여있는 것을 볼 수 있다.)
#spring.jpa.hibernate.ddl-auto=update
  1. 아래코드는 JPA가 자동으로 SQL문을 생성할 때, 생성된 SQL문을 console창에 보여준다. JPA는 직접 SQL을 짜는게 아니다보니까 어떤 SQL문이 들어갔는지 눈으로 확인하면서 하는 것이 안전하다. 꼭 이 설정을 추가해놓고 하는 것을 권장한다.
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
  1. 아래코드는 JPA 를 다루는 hibernate가 발생시키는 log중의 level을 나타낸다. 보통 info 레벨을 많이 보면서 하니까 info로 설정하는 것을 권장한다.
logging.level.org.hibernate=info

CRUD 구현

MemberEntity

간단히 member 라는 엔티티를 만들어서 CRUD를 해보곘다.
member 엔티티에 다음과 같은 컬럼들을 추가하고

롬복처리, 생성자처리, 빌더처리를 해주고 Entity라는 것을 알려주기위해 @Entity 에너테이션도 추가해준다.

이제 Entity라는 '이 Entity가 사용하는 실제 Table이름을 이것이다!' 라는 의미의 @Table 에너테이션을 입력해주어야 한다.

다음
제약조건을 걸어줘야 하는데

  • @Id = Primary_key
  • @column = password 같은 경우 정보수정 말고 별도의 password 수정을 하는 경우가 많은데, myBatis 처럼 필요한 컬럼만 가져와서 하는 것이 아니기때문에 '이 컬럼은 전체 테이블이 변경될 때 같이 변하는 컬럼이 아닙니다.' 라는 의미의 에너테이션이다.
  • @Transient = entity에는 존재하는 컬럼이지만 DB와 무관한 경우 붙여준다.

MemberRepository

mapper역할을 하는 repository는 JPA에서 이미 인터페이스 default 메서드로 지정한 것들을 사용하면 된다. 그래서 JpaRepository 인터페이스를 상속받아서 사용하면 된다.

이제 상속받은 default 메서드를 사용하면 되니까 더이상 건들 것이 없다.

Service, ServiceImpl

MemberService 에서 간단히 CRUD 메서드를 생성한다.

MemberServiceImpl 에서 오버라이드 한다.

repository에서 기본으로 제공하는 CRUD 메서드를 이용하면 된다.

C(Create): save()
R(Read): findAll() / findById()
U(Update): save()
D(Delete): DeleteById()

기능이 많지만 가장 간단한 기능의 메서드인데 특이한 점이 C와 U를 같은 메서드에서 담당한다. JPA는 DB안에 입력받은 값이 있다면 Update를 하고 입력받은 값이 없다면 Intert를 해주기때문에 save() 메서드 하나로 C와 U의 기능을 동시에 수행 가능하다.

HomeContoller

따로 form을 만들거나 하는게 아니라 console에 찍는 것이기 때문에 Home에서 바로 기능을 실행해보겠다.

JPA Insert Contoller 기능 실행 (C)


(파일이 날아가서 다른 코드를 참조했다.)

insert 요청이 들어왔을때 builder 패턴으로 각 데이터값을 컬럼에 넣고 service에서 register(insert) 해준다.
home에서 '/ginsert' 으로 가는 요청 a태그를 만들어놨는데 GInsert를 클릭하면

앞서 설정한 설정값으로 인하여 Hibernate가 실행하는 SQL 구문을 console에 직접 보여준다.

JPA Update Controller 기능 실행 (U)


(파일이 날아가서 다른 코드를 참조했다.)

update 요청이 들어왔을때 builder 패턴으로 각 데이터값을 컬럼에 넣고 service에서 register(insert) 해준다.
home에서 '/gupdate' 으로 가는 요청 a태그를 만들어놨는데 GUpdate를 클릭하면

insert와 마찬가지로 앞서 설정한 설정값으로 인하여 Hibernate가 실행하는 SQL 구문을 console에 직접 보여준다.

(82번을 업데이트했다.)

JPA List Controller 기능 수행 (R)


(파일이 날아가서 다른 코드를 참조했다.)

list 요청이 들어왔을때 DB를 list 컬렉션에 담고 forEach를 사용해서 출력해줬다.

요청을 주면 console에 그동안 insert 했던 DB값이 출력된다.
(잘 보면 앞서 update했던 82번만 DB값이 다르다는 것을 확인할 수 있다.)

JPA Delete Controller 기능 수행 (D)


82번을 삭제해보겠다. 쿼리스트링으로 직접 요청할 것이다.

직접 요청하면 콘솔에 삭제 성공 로그가 뜨고

다시 리스트를 보면 82번이 지워졌다.

느낀점

JPA라는 것이 너무 생소했다. 솔직히 처음에는 'MyBatis만 제대로 알아도 충분하지 않나?' 생각했는데 검색을 하다가 강사님 말씀대로 JPA가 요즘 대세라는 것을 알게되었다.
전자정부프레임워크로 MyBatis가 좀더 유명헀지만 최근 스타트업 회사를 중심으로 JPA를 많이 쓰는 추세라는 것을 알게되었다.
(참조: https://www.elancer.co.kr/blog/view?seq=231)

그래서 JPA에 관해서 한번 정리하는 기록을 남겨야겠다고 생각했는데, 다시 정리하면서 해보니까 또 별거아닌거 같기도하다. (물론 아직 완전 간단한거만 해서 그런것 같긴 하지만..)

profile
Hello World! 안녕하세요

0개의 댓글