Hamutaro - Hamtaro 4

Backend/Java

[JPA] JPA (Java Persistence API) ๋ž€?

carsumin 2025. 11. 7. 20:12
JPA ๋ž€?
  • ์ž๋ฐ”์—์„œ ๊ฐ์ฒด๋ฅผ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”๊ณผ ์ž๋™์œผ๋กœ ๋งคํ•‘ํ•ด์ฃผ๋Š” ORM(Object-Relational Mapping) ๊ธฐ์ˆ 
  • SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ์ €์žฅ,์กฐํšŒ,์ˆ˜์ •,์‚ญ์ œํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ

 

๊ทธ๋ ‡๋‹ค๋ฉด ์™œ JPA๋ฅผ ์‚ฌ์šฉํ• ๊นŒ? 
  • MyBatis์ฒ˜๋Ÿผ SQL ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด ํ…Œ์ด๋ธ” ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€”๋•Œ๋งˆ๋‹ค SQL ์ˆ˜์ •ํ•ด์•ผ ํ•จ
  • ํ•˜์ง€๋งŒ JPA๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ํ…Œ์ด๋ธ”์„ ๋งคํ•‘ํ•ด๋‘๋ฉด SQL์€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋จ
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Œ

 

JPA ๊ธฐ๋ณธ ๊ตฌ์„ฑ ์š”์†Œ
๊ตฌ์„ฑ ์š”์†Œ ์„ค๋ช…
Entity DB ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋˜๋Š” ์ž๋ฐ” ํด๋ž˜์Šค 
Repository CRUD๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค
EntitiyManager JPA์˜ ํ•ต์‹ฌ ๊ฐ์ฒด. ์—”ํ‹ฐํ‹ฐ ์ €์žฅ, ์กฐํšŒ ๊ด€๋ฆฌ
Persistence Context ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ 1์ฐจ ์บ์‹œ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ์˜์—ญ

 

 

์˜ˆ์‹œ
@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;
    
    private String name;
    private String email;
}
  • @Entity : ์ด ํด๋ž˜์Šค๊ฐ€ DB์˜ ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋œ๋‹ค๋Š” ์˜๋ฏธ (Member -> member ํ…Œ์ด๋ธ”)
  • @Id : ๊ธฐ๋ณธ ํ‚ค(PK) ์ง€์ •
  • @GeneratedValue : ์ž๋™ ์ฆ๊ฐ€ ์ „๋žต ์ง€์ • (AUTO, IDENTITY ๋“ฑ) -> PK๊ฐ’ ์ž๋™ ์ƒ์„ฑ
  • ๋‚˜๋จธ์ง€ ํ•„๋“œ๋Š” ์ปฌ๋Ÿผ์œผ๋กœ ์ž๋™ ๋งคํ•‘ (name, email)

-> Member ๊ฐ์ฒด๋ฅผ JPA๊ฐ€ DB ํ…Œ์ด๋ธ”์— ์ž๋™์œผ๋กœ ์ €์žฅ-์กฐํšŒํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ

 

public interface MemberRepository extends JpaRepository<Member, Long> {
	List<Member> findByName(String name);
}
  • JpaRepository๋ฅผ ์ƒ์†ํ•˜๋ฉด CRUD ๋ฉ”์„œ๋“œ (save, findAll, deleteById) ๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ
  • ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฟผ๋ฆฌ ์ž๋™ ์ƒ์„ฑ
    • findByName("ํ™๊ธธ๋™") ์ด๋ฉด SELECT * FROM member WHERE name = 'ํ™๊ธธ๋™'
  • ๋ณ„๋„์˜ SQL ์—†์ด ๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ์œผ๋กœ ์กฐ๊ฑด ๊ฒ€์ƒ‰์ด ๊ฐ€๋Šฅํ•จ

 

@RestController
@RequiredArgsConstructor
public class MemberController {
	
    private final MemberRepository memberRepository;
    
    @PostMapping("/member")
    public Member save(@RequestBody Member member){
    	return memberRepository.save(memeber);
    }
    
    @GetMapping("/member/{id}")
    public Memeber find(@PathVariable Long id){
    	return memberRepository.findById(id).orElseThrow();
    }
}
  • @RestController : REST API ์ปจํŠธ๋กค๋Ÿฌ์ž„์„ ๋ช…์‹œ (JSON ์‘๋‹ต ์ž๋™ ์ฒ˜๋ฆฌ)
  • @RequiredArgsConstructor : final ํ•„๋“œ (memberRepository) ๋ฅผ ์ƒ์„ฑ์ž ์ฃผ์ž…
  • @PostMapping("/member") : ํšŒ์› ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญ ๋ณธ๋ฌธ(JSON)์œผ๋กœ ๋ฐ›์•„ DB์— ์ €์žฅ
  • @GetMapping("/member/{id}") : id๋กœ ํŠน์ • ํšŒ์›์„ ์กฐํšŒ
  • ๋‚ด๋ถ€์—์„œ Repository๊ฐ€ ์•Œ์•„์„œ SQL์„ ์‹คํ–‰ํ•˜๋ฏ€๋กœ ์ง์ ‘ ์ฟผ๋ฆฌ ์งœ์ง€ ์•Š์Œ

< ์‹คํ–‰ ํ๋ฆ„ ์š”์•ฝ >

1. ์‚ฌ์šฉ์ž๊ฐ€ /member๋กœ POST ์š”์ฒญ ๋ณด๋ƒ„
2. Controller๊ฐ€ JSON -> Member ๊ฐ์ฒด๋กœ ๋งคํ•‘
3. Repository.save() ํ˜ธ์ถœ -> JPA๊ฐ€ INSERT SQL ์ƒ์„ฑ ๋ฐ ์‹คํ–‰
4. ์ดํ›„ GET /member/{id} ์š”์ฒญ ์‹œ -> JPA๊ฐ€ SELECT SQL ์‹คํ–‰ ํ›„ ๊ฐ์ฒด ๋ฐ˜ํ™˜

 

-> ์ฝ”๋“œ์ƒ์—๋Š” SQL์ด ์—†์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” JPA๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ SQL์„ ๋งŒ๋“ค์–ด ์‹คํ–‰ํ•จ

 

 

์ฃผ์š” ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ฆฌ
@Entity ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋˜๋Š” ํด๋ž˜์Šค
@Id ๊ธฐ๋ณธํ‚ค(PK) ์ง€์ •
@GeneratedValue PK ์ž๋™ ์ƒ์„ฑ ์ „๋žต
@Column ์ปฌ๋Ÿผ๋ช…, ์ œ์•ฝ์กฐ๊ฑด ์„ค์ •
@OneToMany, @ManyToOne ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘
@Transactional ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„ ๊ด€๋ฆฌ

 

 

์ •๋ฆฌ
  • JPA๋Š” SQL์„ ์ž๋™ ์ƒ์„ฑํ•˜์ง€๋งŒ ๋‚ด๋ถ€์—์„œ SQL์ด ์‹คํ–‰๋จ
  • ORM์€ SQL์„ ๋Œ€์ฒดํ•˜๋Š” ๊ฐœ๋…์ด ์•„๋‹˜, ์ถ”์ƒํ™” ๊ฐœ๋…์œผ๋กœ ์ดํ•ดํ•ด์•ผ ํ•จ
  • ์„ฑ๋Šฅ ํŠœ๋‹์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ