1. JPA 기본 애노테이션
@Entity
JPA가 관리하는 엔티티 클래스에 붙여주는 어노테이션!
데이터베이스 테이블과 자바 클래스 간의 매핑을 정의한다.
@id
Primary Key(PK)에 붙여주는 어노테이션
@Table(name ="")
클래스명과 테이블명이 다를때, 테이블 명을 명시해준다.
@Column(name="")
필드명과 테이블 컬럼명이 다를 때, 컬럼명을 명시해준다.
2. JPA 예시 코드 (스프링부트 없이)
⭐참고로 스프링부트 없이 JPA를 공부하고 있고, lombok라이브러리도 안쓰고 있다.
1) 회원등록
✅JPA 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//JPA는 트랜잭션이 중요하다.
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member member = new Member();
member.setId(1L);
member.setName("ururuwave");
em.persist(member);
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
emf.close();
}
}
✅Member 테이블과 매핑되는 member 객체
package hellojpa;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name="member")
public class Member {
@Id
private Long id;
private String name;
//Getter와 Setter
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
2) 회원조회
✅JPA 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//JPA는 트랜잭션이 중요하다.
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member findMember = em.find(Member.class, 1L);
System.out.println("findMember.getId() = " + findMember.getId());
System.out.println("findMember.getName() = " + findMember.getName());
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
//
em.close();
emf.close();
}
}
💡분명 테이블에 member를 insert했는데 조회를 했더니 아무 값도 없다면? 설정파일을 수정하자.
JPA의 기본 설정에서는 애플리케이션이 시작될 때 데이터베이스 스키마를 생성하거나 초기화하는 작업을 수행한다.
스키마를 유지하려면 'update'로 설정되어있어야한다.
persistence.xml 설정파일로 가서 "create"로 되어있던 것을 "update"로 바꿔줬다.
<property name="hibernate.hbm2ddl.auto" value="update" />
🤔처음에 조회를 할때, 아무 값도 없어서 헤맸는데 이 설정 때문이었다.
Hibernate:
select
m1_0.id,
m1_0.name
from
member m1_0
where
m1_0.id=?
findMember.getId() = 1
findMember.getName() = ururuwave
이제 조회 성공!
3) 회원 수정
✅JPA 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//JPA는 트랜잭션이 중요하다.
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member findMember = em.find(Member.class, 1L);
findMember.setName("Hello,Ururuwave"); //회원 수정
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
//
em.close();
emf.close();
}
}
회원을 찾은 다음에, 그 회원에 setName을 해주면 된다.
조회를 해보면 수정이 잘 된것을 볼 수 있다.
4) 회원 삭제
✅JPA 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//JPA는 트랜잭션이 중요하다.
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member findMember = em.find(Member.class, 1L);
em.remove(findMember); //EntityManager에 remove메서드 이용
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
//
em.close();
emf.close();
}
}
멤버를 찾고, em.remove(찾은멤버)를 하면 삭제가 된다.
콘솔 확인
Hibernate:
select
m1_0.id,
m1_0.name
from
member m1_0
where
m1_0.id=?
Hibernate:
/* delete for hellojpa.Member */delete
from
member
where
id=?
selec쿼리와 delete쿼리가 잘 돌아간 것을 볼 수 있다.
3. 스프링부트와 함께 쓰는 JPA 코드
🤔나는 스프링부트를 쓸 건데!!스프링부트에서는 JPA를 어떤 구조로 쓰게 될까?
스프링부트 환경이고 사용자에게 form형식으로 정보를 받아서 member 테이블에 저장하고 member를 조회하는 상황이라고 가정해보자.
✅애플리케이션 실행부
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
기존 실행부에 비해 아주 간단해졌다.
main에서 애플리케이션을 실행해주기만 하면 된다.
✅Member 엔티티 클래스
package com.example.demo.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters and Setters
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;
}
}
@GeneratedValue(strategy = GenerationType.IDENTITY)
-> id는 자동으로 1씩 증가하도록 했다.
나머지 Getter, Setter를 만들어줬다.
롬복 라이브러리를 쓰면 @Getter, @Setter 어노테이션만 클래스 위에 붙여주면 된다.
✅MemberRepository 인터페이스
package com.example.demo.repository;
import com.example.demo.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemberRepository extends JpaRepository<Member, Long> {
}
여기는 데이터베이스와 상호작용을 하는 메서드를 넣어주면 된다.
JPA는 리포지토리 인터페이스를 통해서 CRUD연산을 자동으로 하게끔 메서드를 제공해준다.
ex) save(), findById(), findAll(), deleteById() 등
메서드 이름을 기반으로 JPA쿼리를 자동 생성할 수 있다.
✅MemberService 클래스
package com.example.demo.service;
import com.example.demo.entity.Member;
import com.example.demo.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class MemberService {
@Autowired
private MemberRepository memberRepository;
//회원등록
@Transactional
public Member saveMember(Member member) {
return memberRepository.save(member);
}
//회원조회
@Transactional
public Member getMember(Long id) {
return memberRepository.findById(id).orElse(null);
}
//회원수정
@Transactional
public Member updateMember(Long id, Member memberDetails) {
Member member = memberRepository.findById(id).orElseThrow(()
-> new RuntimeException("Member not found"));
member.setName(memberDetails.getName());
// 필요한 경우 다른 속성들도 업데이트
return memberRepository.save(member);
}
//회원삭제
@Transactional
public void deleteMember(Long id) {
Member member = memberRepository.findById(id).orElseThrow(()
-> new RuntimeException("Member not found"));
memberRepository.delete(member);
}
}
✔️리포지토리의 메서드를 호출해서 비즈니스 로직을 처리한다.
그래서 MemberRepository에 별도로 메서드를 정의해주지 않아도 된다.
✔️member를 조회했더니 null이라면 람다식을 이용해서 "Member not found"라는 메시지를 보여준다.
✅MemberController 클래스
package com.example.demo.controller;
import com.example.demo.entity.Member;
import com.example.demo.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/members")
public class MemberController {
@Autowired
private MemberService memberService;
//회원등록
@PostMapping
public Member createMember(@RequestBody Member member) {
return memberService.saveMember(member);
}
//회원조회
@GetMapping("/{id}")
public Member getMember(@PathVariable Long id) {
return memberService.getMember(id);
}
//회원수정
@PutMapping("/{id}")
public Member updateMember(@PathVariable Long id, @RequestBody Member memberDetails) {
return memberService.updateMember(id, memberDetails);
}
//회원삭제
@DeleteMapping("/{id}")
public void deleteMember(@PathVariable Long id) {
memberService.deleteMember(id);
}
}
✔️컨트롤러 클래스에서는 MemberService클래스를 사용해서 클라이언트 요청을 처리하고 RESTful API 엔드포인트를 제공한다.
✔️회원 조회, 수정, 삭제의 엔드포인트가 같은 이유는 HTTP 메소드를 통해 다른 작업을 수행할 수 있기때문이다.
-
이제 프론트엔드단에서 회원가입 form을 이용해서 가입요청을 하면 POST로 /member 엔드포인트에 요청을 보내게 될 것이고, 그럼 위 코드에 따라 Member테이블에 사용자의 id와 name정보가 저장될 것이다.
회원 정보 조회를 할 때는 GET 메서드로 /member/{id} 엔드포인트에 요청을 보내면
DB에서 사용자의 정보를 불러올 수 있다.
회원 정보 조회를 할 때는 PUT 메서드로 /member/{id} 엔드포인트에 요청을 보내면
DB에서 사용자의 정보를 수정할 수 있다. (PATCH 메서드를 이용해도 된다.)
회원 정보 조회를 할 때는 DELETE 메서드로 /member/{id} 엔드포인트에 요청을 보내면
DB에서 사용자의 정보를 삭제할 수 있다.
'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
JPA 기본 | 기본키 매핑 | @id, @GeneratedValue (0) | 2024.06.10 |
---|---|
JPA 기본 | 필드와 컬럼 매핑 | @Column, @Enumerated, @Temporal, @Lob (0) | 2024.06.10 |
JPA 기본 | 데이터베이스 스키마 자동 생성 옵션 (0) | 2024.06.10 |
JPA 기본 | @Entity (0) | 2024.06.10 |
JPA 기본 | 영속성 컨텍스트 (0) | 2024.06.08 |