자바 ORM 기술에 대한 표준 명세로, JAVA에서 제공하는 API이다.
JPA는 기존의 반복 코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다.
JPA를 사용하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환을 할 수 있다.
JPA를 사용하면 개발 생산성을 크게 높일 수 있다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
//=========================add=========================
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
//=========================add=========================
testImplementation 'org.springframework.boot:spring-boot-starter-test'
runtimeOnly 'mysql:mysql-connector-java'
}
spring-boot-starter-data-jpa 라이브러리를 추가하면 spring-boot-starter-jdbc는 자동으로 추가가 되기 때문에 build.gradle에 명시를 하지 않아도 된다.
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
실행 시 콘솔에 sql을 보여주는 지 여부
만약 객체에 해당하는 테이블이 없을 경우 자동으로 생성하는 지에 대한 여부
package com.rptp.rptpSpringBoot.model;
import javax.persistence.*;
@Entity(name = "member")
public class MemberDTO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
//@Column(name="name")
private String name;
jpa에게 해당 클래스를 table로 매핑
해당 필드를 pk로 인식
입력시 만약 id가 null이라면 자동으로 id에 값 설정
해당 필드를 일반 컬럼으로 지정, 만약 위 처럼 name과 필드명이 같으면 생략 가능
package com.rptp.rptpSpringBoot.repository.impliment;
import com.rptp.rptpSpringBoot.model.MemberDTO;
import com.rptp.rptpSpringBoot.repository.MemberRepository;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
@Repository
public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
public MemberDTO save(MemberDTO memberDTO) {
em.persist(memberDTO);
return memberDTO;
}
@Override
public Optional<MemberDTO> findById(Long id) {
MemberDTO memberDTO = em.find(MemberDTO.class, id);
return Optional.ofNullable(memberDTO);
}
@Override
public Optional<MemberDTO> findByName(String name) {
List<MemberDTO> result = em.createQuery("select m from member m where m.name = :name", MemberDTO.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<MemberDTO> findAll() {
return em.createQuery("select m from member m", MemberDTO.class)
.getResultList();
}
}
그대로 엔티티를 관리하는 객체이다.
EntityManager를 통해 테이블과 매핑된 엔티티를 실제로 사용하게 된다
영속성 컨텍스트를 통해서 엔티티를 영속화 한다
쿼리를 생성한다.
문자열에서 "member"과 매핑되는 것은 DTO에서 설정한 Entity네임이다.
문자열 내 파라미터는 ':'로 입력받는다.
package com.rptp.rptpSpringBoot.service;
import com.rptp.rptpSpringBoot.model.MemberDTO;
import com.rptp.rptpSpringBoot.repository.MemberRepository;
import com.rptp.rptpSpringBoot.repository.impliment.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
//화원가입
//================ADD================
@Transactional
//================ADD================
public Long join(MemberDTO memberDTO) {
// 같은 이름의 있는 중복 회원 x
validateDuplicateMember(memberDTO);
memberRepository.save(memberDTO);
return memberDTO.getId();
}
private void validateDuplicateMember(MemberDTO memberDTO) {
memberRepository.findByName(memberDTO.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다");
});
}
//전체 회원 조회
public List<MemberDTO> findMembers() {
return memberRepository.findAll();
}
// id에 맞는 회원 조회
public Optional<MemberDTO> findOne(Long memberId) {
return memberRepository.findById(memberId);
}
}
DB에서 데이터를 입력, 수정, 삭제 하는 메서드에 달아주는 에너테이션이다.
클래스에도 달 수 있는데, 해당 클래스에 속해있는 모든 메서드가 @Transactional 기능이 생긴다.
테스트 코드를 통과하는 것을 볼 수 있다.
회원가입을 하면 성공적으로 입력 되는 것을 볼 수 있다.
콘솔에 어떤 명령어가 입력되었는지도 확인할 수 있다.
spring framework에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트
CRUD 처리를 위한 공통 인터페이스 제공
repository 개발 시 인터페이스만 작성하면 실행 시점에 스프링 데이터 JPA가 구현 객체를 동적으로 생성해서 주입
데이터 접근 계층을 개발할 때 구현 클래스 없이 인터페이스만 작성해도 개발을 완료할 수 있도록 지원
package com.rptp.rptpSpringBoot.repository;
import com.rptp.rptpSpringBoot.model.MemberDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
//JpaRepository을 extend받으면 자동으로 Spring 컨테이너에 Bean으로 알아서 입력됨.
public interface SpringDataJpaMemberRepository extends JpaRepository<MemberDTO, Long> , MemberRepository{
@Override
//sql: select m from member m where m.name = ?
Optional<MemberDTO> findByName(String name);
}
이게되네;;
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/lecture/49597
JPA란 https://gmlwjd9405.github.io/2019/08/04/what-is-jpa.html
영속성이란 https://sugerent.tistory.com/587
Spring Data JPA https://data-make.tistory.com/621