๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/Spring

[Spring] DAO์™€ DTO์˜ ์ฐจ์ด ๊ทธ๋ฆฌ๊ณ  VO

by ์•ˆ์ฃผํ˜• 2022. 4. 14.

์„œ๋ก 

DAO์™€ DTO์˜ ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋˜ ์ค‘ DTO์— ๋Œ€ํ•ด์„œ๋Š” ์•Œ๊ณ  ์žˆ์ง€๋งŒ DAO๋Š” ์•„๋ฌด๋ฆฌ ๋ด๋„ Repository ๊ฐ™์€๋ฐ ๊ฐ™์€ ๊ฐœ๋…์ธ์ง€ ๊ถ๊ธˆํ•ด์„œ ์ •๋ฆฌํ•ด ๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์„ ๋จผ์ € ๋ง์”€๋“œ๋ฆฌ๋ฉด Repository ํŒจํ‚ค์ง€๊ฐ€ DAO์ž…๋‹ˆ๋‹ค.

 

1. DAO(Data Access Object)

DAO๋Š” ์‹ค์ œ๋กœ DB์˜ data์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

  • ์‹ค์ œ๋กœ DB์— ์ ‘๊ทผํ•˜์—ฌ data๋ฅผ ์‚ฝ์ž…, ์‚ญ์ œ, ์กฐํšŒ, ์ˆ˜์ • ๋“ฑ CRUD ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • Service์™€ DB๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณ ๋ฆฌ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • Repository package๊ฐ€ ๋ฐ”๋กœ DAO์ž…๋‹ˆ๋‹ค.
@Repository
@RequiredArgsConstructor
public class MemberRepository {

    private final EntityManager em;

    public void save(Member member) {
        em.persist(member);
    }

    public Member findOne(Long id) {
        return em.find(Member.class, id);
    }

    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class).getResultList();
    }

    public List<Member> findByName(String name) {
        return em.createQuery("select m from Member m where m.name =:name", Member.class)
                .setParameter("name", name)
                .getResultList();
    }
}

 

2. DTO(Data Transfer Object)

DTO๋Š” ๊ณ„์ธต ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด๋กœ, DTO๋Š” ๋กœ์ง์„ ๊ฐ€์ง€์ง€ ์•Š๋Š” ์ˆœ์ˆ˜ํ•œ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด(Java Beans)์ž…๋‹ˆ๋‹ค.

  • DTO๋Š” ์ฆ‰, getter/setter ๋ฉ”์„œ๋“œ๋งŒ ๊ฐ€์ง„ ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • DB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์–ด์„œ Service๋‚˜ Controller ๋“ฑ์œผ๋กœ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ฆ‰ ์—”ํ‹ฐํ‹ฐ๋ฅผ DTO ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•œ๋ฒˆ ์˜ˆ์‹œ ์ฝ”๋“œ๋กœ ์ •๋ฆฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. domain(Entity) logic
  2. DTO logic
  3. Controller logic

1) ๋จผ์ € ์•„๋ž˜์™€ ๊ฐ™์€ Entity๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค.

@Entity
@Getter
@Setter
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
	private int age;

}

2) ์•„๋ž˜๋Š” DTO class์ž…๋‹ˆ๋‹ค.

    @Getter
    @Setter
    static class ResponseDto {
        private String name;
        private String result = "๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.";

        public ResponseDto(Member member) {
            name = member.getName();
        }
    }

3) ์•„๋ž˜๋Š” Controller logic์ž…๋‹ˆ๋‹ค.

    @PostMapping("api/useDTO")
    @ResponseBody
    public ResponseDto useDTO(@RequestParam String name, @RequestParam Long id) {
    	Member findMember = memberService.findOne(id);
        return new ResponseDto(findMember);
    }
    
    @PostMapping("api/notUseDTO")
    @ResponseBody
    public FindMember notUseDTO(@RequestParam String name, @RequestParam Long id) {
        Member findMember = memberService.findOne(id);
        return new FindMember(findMember);
    }

๊ฒฐ๊ณผ

useDTO ๋ฉ”์„œ๋“œ๋Š” Entitiy์˜ ๊ฒฐ๊ณผ๋ฅผ DTO๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ์ธ name๊ณผ result๋งŒ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ notUseDTO๋Š” Member์—”ํ‹ฐํ‹ฐ์˜ ๋ชจ๋“  ์ •๋ณด ์ฆ‰, ์—”ํ‹ฐํ‹ฐ ๊ทธ ์ž์ฒด๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ์˜ˆ์‹œ๋Š” DTO๋ฅผ Response์—๋งŒ ์ด์šฉํ–ˆ์ง€๋งŒ Request์—ญ์‹œ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

3. VO(value Object)

VO๋Š” DTO์™€ ๋‹ฌ๋ฆฌ Read-Only์†์„ฑ์„ ์ง€๋‹Œ ๊ฐ’ ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค. DTO๋Š” setter๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์„œ ๊ฐ’์ด ๋ณ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ VO์˜ ๊ฒฝ์šฐ์—๋Š” getter๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์„œ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

DTO์™€ VO์˜ ์ฐจ์ด์ ์€ DTO๋Š” ์ธํ„ฐํ„ด์Šค ๊ฐœ๋…์ด๊ณ , VO๋Š” ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. VO๋Š” ๊ฐ’๋“ค์— ๋Œ€ํ•ด Read-Only๋ฅผ ๋ณด์žฅํ•ด์ค˜์•ผ ์กด์žฌ์˜ ์‹ ๋ขฐ์„ฑ์ด ํ™•๋ณด๋˜์ง€๋งŒ DTO์˜ ๊ฒฝ์šฐ์—๋Š” ๋‹จ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๊ทธ๋ฆ‡์˜ ์—ญํ• ์ผ ๋ฟ ๊ฐ’์€ ๊ทธ์ € ์ „๋‹ฌ๋˜์–ด์•ผ ํ•  ๋Œ€์ƒ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ’ ์ž์ฒด์— ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” VO์™€ ์ „๋‹ฌ๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์กดํ•ด์•ผ ํ•˜๋Š” DTO์˜ ํŠน์„ฑ์ƒ ๊ฐœ๋…์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ VO์˜ ํ•ต์‹ฌ์€ ๋‘ ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ•„๋“œ ๊ฐ’๋“ค์ด ๋™์ผํ•˜๋ฉด ๋‘ ๊ฐ์ฒด๋Š” ๊ฐ™๋‹ค์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์™„์ „ํžˆ ๊ฐ’ ์ž์ฒด ํ‘œํ˜„ ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋ชฉ์ ์ด๋ผ๋ฉด, ๋‘ ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ•„๋“œ ๊ฐ’๋“ค์ด ๋ชจ๋‘ ๊ฐ™์œผ๋ฉด ๊ฐ™์€ ๊ฐ์ฒด์ด๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ(equals() ์™€ hashCode()์˜ ์˜ค๋ฒ„๋ผ์ด๋”ฉ)์ด ์ค‘์š”ํ•˜์ง€, ๋ฉ”์†Œ๋“œ๋Š” ์–ด๋–ค ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋“  ๋ง๋“  ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค.

 

DTO์™€ VO ์ฐจ์ด

์ข…๋ฅ˜ ์šฉ๋„ ๋™๋“ฑ ๊ฒฐ์ • ๊ฐ€๋ณ€ / ๋ถˆ๋ณ€ ๋กœ์ง
DTO - ๊ณ„์ธต ๊ฐ„ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ - ์†์„ฑ๊ฐ’์ด ๋ชจ๋‘ ๊ฐ™์•„๋„ ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ์Œ - setter ์กด์žฌ ์‹œ ๊ฐ€๋ณ€,
- setter ๋น„ ์กด์žฌ ์‹œ ๋ถˆ๋ณ€
- getter/setter ์ด์™ธ์˜ ๋กœ์ง์ด ๋ถˆํ•„์š”ํ•จ
VO - ๊ฐ’ ์ž์ฒด๋ฅผ ํ‘œํ˜„ - ์†์„ฑ๊ฐ’์ด ๋ชจ๋‘ ๊ฐ™์œผ๋ฉด ๊ฐ™์€ ๊ฐ์ฒด - ๋ถˆ๋ณ€ - getter/setter ์ด์™ธ์˜ ๋กœ์ง์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ

 

๋Œ“๊ธ€