스프링 DB 접근 기술- JPA
2022. 8. 5. 23:46ㆍ2022/Spring
JPA
JDBC에서 JDBC Template으로 바뀌면서 개발자가 작성해야하는 반복된 코드는 확 줄었지만 SQL은 직접 모두 작성해야했다. 그런데 JPA는 이런 기본 SQL도 직접 만들어서 실행해준다.
또한 SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환할 수 있다. 따라서 개발 생산성을 높일 수 있게된다.
마치 객체를 메모리(memoryMemberRepository)에 넣듯이 JPA가 중간에서 DB에 SQL을 날리고, DB에서 데이터를 가져오는 것을 처리한다.
JPA 라이브러리 추가 및 설정
Entity 맵핑
JPA는 인터페이스만 제공이 되는 것이다. hybernate, eclipse 등이 구현 기술이 된다. 즉, JPA 인터페이스에 hybernate만 사용한다고 생각해도 무방하다. - jpa, hybernate 라이브러리가 있는지 확인
JPA는 객체와 ORM(Object, Relational DB, Mapping(by @))의 기술이다.
package hello.hellospring.domain;
import javax.persistence.*;
//jpa가 관리하는 entity
@Entity
public class Member {
//PK 값, DB에서 자동 생성되는 값 = Identity 전략
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; //시스템이 정하는 임의의 값
//DB의 컬럼명이랑 맵핑
//@Column(name = "username")
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;
}
}
JpaMemberRepository
package hello.hellospring.repositroy;
import hello.hellospring.domain.Member;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
public class JpaMemberRepository implements MemberRepository{
//JPA는 Entity Manager 라는 것으로 모든 것이 동작
// Spring boot가 자동으로 entity mamager라는 것을 생성함 - 내부적으로 DataSource를 모두 가지고 있어서 DB와의 통신 등을 다 처리한다.
private final EntityManager em;
public JpaMemberRepository(EntityManager em){
this.em = em;
}
@Override
public Member save(Member member) {
//JPA가 insert 쿼리 만들어 DB에 집어넣고, set ID까지 다 해준다.
em.persist(member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
//PK
//조회할 타입, 식별자
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
// List를 가지고 조회할 때는 쿼리를 짜야한다. (PK 기반이 아닌 경우, JPQL 써야함)
// JPA 기술을 spring에서 한번 감싸고 제공하는 기술 = spring data jpa 기술 : 아래 예제 마저 쿼리 안짜도 된다.
@Override
public Optional<Member> findByName(String name) {
// JPQL이라는 객체지향 쿼리 언어를 사용해야한다.
List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
//select m from Member m : 테이블이 아닌 객체(Entity)를 대상으로 쿼리를 날림
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
}
@Transactional 추가
SpringConfig 변경
package hello.hellospring;
import hello.hellospring.repositroy.*;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
private EntityManager em;
//DI
@Autowired
public SpringConfig(EntityManager em){
this.em = em;
}
//Configuration을 읽고 스프링 Bean으로 등록하도록 인식
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
//구현체 반환
return new JpaMemberRepository(em);
}
}
테스트
localhost:8080에서 테스트를 해보면 다음과 같은 로그가 나온다.
즉, Hibernate 구현체가 알아서 SQL을 날려 데이터를 insert한다는 것을 알 수 있다.
'2022 > Spring' 카테고리의 다른 글
AOP - AOP가 필요한 상황 (0) | 2022.08.06 |
---|---|
스프링 DB 접근 기술- 스프링 데이터 JPA (0) | 2022.08.06 |
스프링 DB 접근 기술 - 스프링 JDBC Template (0) | 2022.08.05 |
스프링 DB 접근 기술 - 스프링 통합 테스트 (0) | 2022.07.31 |
스프링 DB 접근 기술 - 순수 JDBC (0) | 2022.07.31 |