이번 시간에는 JPA(JAVA Persistence API)에 대해 알아보았다.
초창기의 JDBC에서 JDBC Template으로 바꿨을 때, 코드가 확 줄어든 것을 확인할 수 있었는데,
그래도 아직 sql은 직접 작성을 해야했다.
여기서 JPA를 사용하게 되면, SQL 쿼리도 JPA가 자동으로 처리를 해준다!
객체를 JPA에 넣으면, JPA가 DB에 SQL을 날리거나, DB를 통해서 데이터를 가져오거나 하는 것들을 JPA가 처리해준다~~
이렇듯, JPA를 사용하면 SQL과 데이터 중심의 설계에서 객체 중심의 설계로 전환이 가능하다~~!
그렇기 때문에 개발 생산성이 올라간다!
- JPA 디펜던시 추가 및 세팅
먼저 build.gradle에서 JPA 디펜던시를 추가해준다.
그리고 application.properties에서 설정을 셋팅해준다.
3번째줄에 show-sql을 true로 수정하면 jpa가 날리는 sql을 볼 수가 있다.
4번째줄에 JPA를 사용하면 회원 객체를 보고 테이블도 자동으로 알아서 다 만든다.
그렇기 때문에, 미리 만들어져있는것을 쓰기 위해서는 자동 테이블 생성해주는 기능을 none으로 꺼준다.
JPA를 쓰기 위해서는 엔티티를 매핑을 해줘야한다.
JPA는 인터페이스만 제공이 되고, 구현체로 hibernate, EclipseLink와 같은 구현 기술들이 여러개의 벤더가 있는데,
그중에서 강의중에는 JPA 인터페이스에 hibernate를 쓸 예정이다.
JPA는 ORM(Object Relational Mapping),
즉, 객체와 관계형 데이터베이스 테이블의 매핑을 어노테이션으로 해준다.
@Entity ->
Entitiy 어노테이션을 추가해주면, JPA가 관리하는 엔티티가 된다.
엔티티란, 테이블에 대응하는 하나의 클래스로 보면 된다.
@Id ->
PK로 @Id를 매핑해준다.
@GeneratedValue ->
쿼리에 ID를 넣지 않아도 DB가 자동으로 ID를 생성해주는 것을 아이덴티티 전략이라고 한다.
@Column ->
이름을 DB에 컬럼명이 name으로 되어 있다고 가정하자.
그러면 DB에 있는 컬럼명을 name과 매핑이 된다.
이러한 애노테이션들이 DB와 매핑하는 역할을 한다.
이제 정보들을 가지고 insert, update, delete, select문 과 같은 쿼리들을 만들수 있다.
- JPA 구현
JpaMemberRepository 리포지토리 클래스를 생성해준다.
그리고 EntityManager를 호출하고 생성자를 만들어준다.
EntityManager를 설명하자면, JPA는 모든게 EntityManager를 통해서 동작한다.
gradle을 통해서 JPA 라이브러리를 받게 되면, 스프링 부트가 현재 DB와 연결해서 EntityManager를 자동으로 생성해준다.
그래서 만들어진것을 인젝션 받으면 된다.
EntityManager는 내부적으로 DataSource를 갖고 있어서 DB와 통신을 내부에서 처리를 한다.
결국, JPA를 쓰기 위해서는 EntityManager를 주입받아야 된다.
이제 implements 해준 메소드들을 하나씩 구현하기 시작~~!
persist의 뜻은 영속하다, 혹은 영구 저장하다 라는 뜻!
이렇게 코드를 짜면 JPA가 insert 쿼리를 만들어서 DB에 넣고 ID까지 member 객체에 setId를 해준다.
find메소드는 조회할 타입과 식별자만 넣어주면 select 쿼리문이 날라간다~~
findByName 메소드의 경우는 살짝 다른게,
ID와 같이 PK인 경우는 findById 같이 조회를 할 수 있지만,
Name은 PK가 아니기 때문에 JPQL이라는 객체지향 쿼리 언어를 사용해야된다.
Ctrl + Alt + N 단축키를 누르면 Inline 변수라는 기능이 실행되는데
위의 첫번째 사진에서 세번째 사진처럼 합쳐지게 된다.
JPQL 쿼리 언어인데, 테이블 대상으로 쿼리를 날리는게 아닌, 객체를 대상으로, 즉 entity를 대상으로 쿼리를 날린다.
SQL이랑 비슷하지만 약간 다른점이,
쿼리문도 보면 SQL문이였으면 m.id 혹은 m.name 이런식으로 했을텐데,
select를 m을 입력해서 member 객체 자체를 선택해서 조회함!
그리고 조회 타입은 Member.class를 넣어준다.
서비스에서 Transactional을 추가해준다.
SpringConfig에서 memberRepository 빈 객체의 리턴을 JpaMemberRepository로 설정해주고,
EntityManager를 필요로 하기 때문에, 호출하고 생성자를 만들어준다.
그리고 리턴의 파라미터로 em을 주입해준다!
- JPA 테스트
그리고 테스트 실행하니 정상 작동~~!
처음에는 이렇게 오류가 떴는데 오류를 잘 읽어보니 Member 클래스에서 Column 어노테이션을 name으로 해줘야되는데,
username으로 해서 매핑이 잘못되어 있어서
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not prepare statement
이런 오류가 발생했던 것!ㅜㅜㅜ
그래서 매핑을 수정해주었더니 테스트가 정상 작동한다ㅋㅋㅋㅋ
콘솔에 찍힌 테스트 내용중에,
스프링 데이터 JPA를 세팅하면 기본적으로 Hibernate라는 오픈 소스 구현체가 사용된다. (JPA는 인터페이스임)
DB에는 결국 쿼리가 나가야 되기 때문에, hibernate가 만든 sql 문으로 select 쿼리도 나가고, 아이디가 생성이 된다~~
@Transactional을 어노테이션 했기 때문에 자동으로 롤백이 되지만,
DB에 실제로 저장을 하고 싶으면 테스트 메소드에 @Commit을 어노테이션 하면 된다.
아래는 전체 JpaMemberRepository 코드~~
'개발자 공부 - 인프런 온라인 강의 > 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술' 카테고리의 다른 글
[섹션 7. AOP] AOP가 필요한 상황 & AOP 적용/ 인프런 김영한 스프링 입문 (0) | 2023.02.04 |
---|---|
[섹션 6. 스프링 DB 접근 기술] 스프링 데이터 JPA / 인프런 김영한 스프링 입문 (0) | 2023.02.04 |
[섹션 6. 스프링 DB 접근 기술] 스프링 JdbcTemplate / 인프런 김영한 스프링 입문 (0) | 2023.02.02 |
[섹션 6. 스프링 DB 접근 기술] 스프링 통합 테스트 / 인프런 김영한 스프링 입문 (0) | 2023.02.02 |
[섹션 6. 스프링 DB 접근 기술] 순수 JDBC / 인프런 김영한 스프링 입문 (0) | 2023.02.01 |
[섹션 6. 스프링 DB 접근 기술] H2 데이터베이스 설치(+H2 DB 생성 오류, DB파일 수동으로 만들기) / 인프런 김영한 스프링 입문 (0) | 2023.02.01 |
[섹션 5. 회원 관리 예제 - 웹 MVC 개발] 회원 웹 기능 - 조회 / 인프런 김영한 스프링 입문 (0) | 2023.01.31 |
[섹션 5. 회원 관리 예제 - 웹 MVC 개발] 회원 웹 기능 - 홈 화면 추가 & 회원 웹 기능 - 등록 / 인프런 김영한 스프링 입문 (0) | 2023.01.31 |
댓글