(+)
Jdbc -(1)-> JdbcTemplate -(2)-> Jpa
(1)
반복적인 코드 줄어듦.
but. SQL은 개발자가 직접 작성 해야됨.
(2)
반복적인 코드 줄어듦.
SQL도 JPA가 직접 만들어 실행.
마치 MemoryMemberRepository에서 객체를 메모리에 넣듯이 JPA에 집어넣으면 DB에 query를 날리고, 데이터를 DB에서 가져오고 하는건 JPA가 다 처리해줌.
build.gradle 파일에 JPA, h2 데이터베이스 관련 라이브러리 추가spring-boot-starter-data-jpa 는 내부에 jdbc 관련 라이브러리를 포함한다. 따라서 jdbc는 제거해도 됨.
스프링 부트에 JPA 설정 추가
spring.jpa.show-sql=true
: JPA가 생성하는 SQL을 출력한다.spring.jpa.hibernate.ddl-auto=none
: JPA는 테이블을 자동으로 생성하는 기능을 제공하는데 none 를 사용하면 해당 기능을 끈다.JPA 엔티티 매핑
JPA를 사용하려면 엔티티를 매핑해야함.
(JPA는 인터페이스만 제공되는거고, 그 구현체로 hibermate 등의 구현기술이 있음. -> JPA 인터페이스의 hibermate 사용
JPA는 객체+ORM(Object Relational Mapping.객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해주는 것))
@Entity를 써주면 이제부터 Member는 JPA가 관리하는 엔티티가 됨.
insert into member(name) values('spring1');
하면 id 자동으로 Generate됨.
query를 잘보면 query에 id를 넣는게 아니라 DB에 값을 넣으면 DB가 id를 자동으로 생성해주는 것을 identity라고 함.
@Id @GeneratedValue(stratedgy = GenerationType.IDENTITY)
그래서 strategy에 IDENTITY라고 해줘야됨.
-> 어노테이션들을 가지고 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해줌.
이때 이 정보를 가지고 insert, update, delete, select문을 만들수 있도록 JPA가 동작함.
JPA 회원 리포지토리JPA는 EntityManager로 모든게 동작함.
build.gradle에서 data-jpa 라이브러리를 받으면 springboot가 자동으로 EntityManager을 생성해줌.
(properties에서 JPA 세팅했던 정보들과 데이터베이스 커넥션 정보를 다 연결해서 EntityManager을 생성해줌. 얘는 내부적으로 datasource를 가지고 있어서 DB랑 통신하는 것을 내부에서 다 처리함.)
-> 결론. JPA 쓰려면 EntityManager 주입받아야 함.
save, insert문persist는 영구저장한다는 뜻
persist()에 member을 넣어주고 return member을 해주기만 하면 됨.
이렇게 하면 insert query 만들어서 집어넣어주고 set id까지 해줌.
findById, select문Member member = em.find(Member.class, id);
id 조회하는건 조회할 타입과 식별자 pk값 넣어주면 됨.
findAll, findByNamepk같은 경우는 em.find(Member.class, id);
처럼 조회할 수 있는데 findByName같은 경우에는 JPQL이라는 객체 지향 query언어를 사용해야 함.(거의 SQL과 흡사)
table 대상으로 query을 날리는게 아니라 객체를 대상으로 query를 날림. 그럼 이게 SQL로 번역이 됨.
entity(Member)를 대상으로 query를 날리는 건데 entity(Member) 자체를 select 함(= 객체 자체를 select 함)
Member.class로 조회
서비스 계층에 트랜잭션 추가- org.springframework.transaction.annotation.Transactional
를 사용해야함.
JPA를 사용하도록 스프링 설정 변경
(+) test 돌리다가 오류난거
Description:
Parameter 0 of constructor in hello.hellospring.controller.MemberController required a bean of type 'hello.hellospring.service.MemberService' that could not be found.
Action:
Consider defining a bean of type 'hello.hellospring.service.MemberService' in your configuration.
transactional어노테이션을 넣어주면서 service 어노테이션을 삭제해버림.
MemberService는 순수한 Java Class이고 spring이 이를 구분할 수 있는 방법이 없음.
이를 해결하기 위해 @Service를 MemberService의 public class 위에 넣어줘야 함.
그러면 spring이 뜰때 Service임을 인지하고 Spring container에 등록해줌.(@Service를 써줘야 spring이 자신이 관리하는 부분임을 구분할 수 있음.)
오류없이 잘 실행됨
@transactional 지우고 @commit해서 DB에 잘 저장되는지 확인
오류없이 잘 실행됨...!