Skip to content

JPA Section7

SH-Seol edited this page May 28, 2024 · 1 revision

ํ™ˆ ํ™”๋ฉด๊ณผ ๋ ˆ์ด์•„์›ƒ

  • thymeleaf๋ฅผ ์‹ฌ๋„ ์žˆ๊ฒŒ ์“ฐ๋ ค๋ฉด Hierarchical-style์˜ layouts์„ ์‚ฌ์šฉํ•ด๋ผ.
  • Intellij๊ฐ€ resource๋ฅผ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•˜๋ฉด synchronizeํ•˜๊ณ  rebuildํ•˜์ž
public class MemberForm {

    @NotEmpty(message = "ํšŒ์› ์ด๋ฆ„์€ ํ•„์ˆ˜ ์ž…๋‹ˆ๋‹ค.")
    private String name;

    private String city;
    private String street;
    private String zipcode;
}
@PostMapping("/members/new")
    public String create(@Valid MemberForm form, BindingResult result){
        
        if(result.hasErrors()){
            return "members/createMemberForm";
        }
        
        Address address = new Address(form.getCity(), form.getStreet(), form.getZipcode());
        Member member = new Member();
        member.setName(form.getName());
        member.setAddress(address);
        
        memberService.join(member);
        
        return "redirect:/";
    }
  • @Valid๋ฅผ ํ†ตํ•ด ์œ„ @NotEmpty๋ฅผ ์ ์šฉํ•˜๊ณ , BindingResult๋Š” ์—๋Ÿฌ๋ฅผ ๋‹ด์•„๋‘๊ณ  ์‹คํ–‰ํ•œ๋‹ค.
  • Member๊ฐ€ ์•„๋‹ˆ๋ผ MemberForm์„ parameter๋กœ ๋ฐ›๋Š” ์ด์œ  โ†’ ์‹ฌํ”Œํ•˜๋ฉด ๋ฐ”๋กœ entity๋ฅผ ๋ฐ›์œผ๋ฉด ๋˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ๋Š” ๋‹จ์ˆœํ•˜์ง€ ์•Š์Œ. Form์œผ๋กœ ๋ฐ›๊ณ  controller๋กœ ์ •์žฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ณ , Member๋กœ ๋ฐ›์œผ๋ฉด Member์— ํ•„์š”ํ•œ ์ž‘์—…์„ ํ•ด์•ผํ•ด์„œ ์ ์  ์ง€์ €๋ถ„ํ•ด์ง.

Form์ด๋ƒ Entity๋ƒ?

์š”๊ตฌ์‚ฌํ•ญ์ด ์ •๋ง ๋‹จ์ˆœํ•œ ๊ฒฝ์šฐ์—๋Š” Entity๋ฅผ ์จ๋„ ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์š”๊ตฌ์‚ฌํ•ญ์ด ์‹ค๋ฌด์—์„œ๋Š” ์ผ๋Œ€์ผ ๋งค์นญ์ธ ๊ฒฝ์šฐ๊ฐ€ ๊ฑฐ์˜ ์—†๋‹ค. ๊ทธ๋Ÿฐ ์ƒํ™ฉ์—์„œ Entity๋ฅผ ์“ฐ๋ฉด ๊ฒฐ๊ตญ ํ™”๋ฉด ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— Entity๊ฐ€ ์ง€์ €๋ถ„ํ•ด์ง€๊ณ  ์ด๋Š” ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

  • API๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ์—๋Š” ์ ˆ๋Œ€ Entity๋ฅผ ์™ธ๋ถ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
    • Member Entity๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋ฉด, API์ŠคํŒฉ์ด ๋ณ€ํ™”ํ•˜๊ฒŒ ๋˜๊ณ , ํ•ด๋‹น ์š”์†Œ๊ฐ€ ์™ธ๋ถ€๋กœ ๋…ธ์ถœ์ด ๋œ๋‹ค.
@PostMapping("items/{itemId}/edit")
    public String updateItem(@PathVariable String itemId, @ModelAttribute("form") BookForm form){
        
        Book book = new Book();
        book.setId(form.getId());
        book.setIsbn(form.getIsbn());
        book.setName(form.getName());
        book.setStockQuantity(form.getStockQuantity());
        book.setPrice(form.getPrice());
        book.setAuthor(form.getAuthor());
        
        itemService.saveItem(book);
        
        return "redirect:items";
    }
  • PathVariable๋กœ itemId๋ฅผ ๋„˜๊ธฐ๊ธฐ์— ๋ณด์•ˆ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

    • Session, permission ๋“ฑ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Book์€ ์ƒˆ๋กœ์šด ๊ฐ์ฒด์ด์ง€๋งŒ, ์ด๋ฏธ DB์— ์ €์žฅ๋œ ๊ฒƒ์„ ๊ฐ€์ ธ์™€์„œ ์‹๋ณ„์ž๊ฐ€ ์กด์žฌํ•œ๋‹ค.

  • ์‹๋ณ„์ž๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•œ ๊ฒƒ์€ ๋ฐ”๋กœ ์ค€์˜์† ์—”ํ‹ฐํ‹ฐ๋ผ๊ณ  ํ•œ๋‹ค. JPA๊ฐ€ ๊ด€๋ฆฌ๋ฅผ ์•ˆ ํ•œ๋‹ค. โ†’ ์•„๋ฌด๋ฆฌ ๋ฐ”๊พธ๋”๋ผ๋„ DB๋Š” ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค.

๋ณ€๊ฒฝ ๊ฐ์ง€์™€ ๋ณ‘ํ•ฉ

  • ๋ณ€๊ฒฝ ๊ฐ์ง€ (Dirty checking)
  • ๋ณ‘ํ•ฉ (Merge)

๋ณ€๊ฒฝ ๊ฐ์ง€

@Transactional
    public void updateItem(Long itemId, Book param){
        Item findItem = itemRepository.findOne(itemId);
        findItem.setPrice(param.getPrice());
    }
  • ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ ํ›„ ๋ณ€๊ฒฝํ•  ๊ฐ’ ์„ ํƒ, ์ดํ›„ ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ์ ์— ๋ณ€๊ฒฝ ๊ฐ์ง€(Dirty checking)ํ•˜๊ณ  DB๋ณ€๊ฒฝ

๋ณ‘ํ•ฉ

@Transactional
void update(Item itemParam) { //itemParam: ํŒŒ๋ฆฌ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜จ ์ค€์˜์† ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ
Item mergeItem = em.merge(itemParam);
}
  • ๋™์ž‘ ๋ฐฉ์‹์€ ์•„๋ž˜์˜ ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค.
@Transactional
    public Item updateItem(Long itemId, Book param){
        Item findItem = itemRepository.findOne(itemId);
        findItem.setPrice(param.getPrice());
        return findItem;
    }

Untitled

  • ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ setPrice()๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด findItem.price๋Š” null์ด ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ตœ๋Œ€ํ•œ merge๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  DirtyChecking์„ ์“ฐ์ž.
@Transactional
    public void updateItem(Long itemId, String name, int price, int stockQuantity){
        Item findItem = itemRepository.findOne(itemId);
        findItem.setName(name);
        findItem.setPrice(price);
        findItem.setStockQuantity(stockQuantity);
    }
  • ์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ๋ฐ”๊พธ๊ณ  dirty checkingํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ๋งŒ์•ฝ ๋ฐ”๊ฟ€ ๊ฒƒ์ด ๋„ˆ๋ฌด ๋งŽ๋‹ค๋ฉด dto๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • setter์—†์ด entity์•ˆ์—์„œ ๋ฐ”๋กœ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
@Transactional
public void updateItem(Long itemId, String name, int price, int stockQuantity){
    Item findItem = itemRepository.findOne(itemId);
    findItem.updateDetails(name, price, stockQuantity);
}