๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

ํ”„๋กœ์ ํŠธ/๊ธฐํƒ€

์ˆ˜์Šต๊ณผ์ œ ๊ฒŒ์‹œํŒ ๊ตฌํ˜„ํ•˜๋ฉฐ ๋‚˜๋Š” ๋ฌด์—‡์„ ๋ฐฐ์› ๋‚˜?

์ˆ˜์Šต๊ธฐ๊ฐ„ 4์ฃผ ๋™์•ˆ '๊ฒŒ์‹œํŒ ๋งŒ๋“ค๊ธฐ' ๊ณผ์ œ๋ฅผ ๋ถ€์—ฌ๋ฐ›์•˜๋‹ค. ์ด ๊ธ€์€ ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๋‚˜๋Š” 1๋‹ฌ์ด๋ผ๋Š” ๊ธด ์‹œ๊ฐ„ ๋™์•ˆ ๋ฌด์—‡์„ ๋ฐฐ์› ๋Š”์ง€ ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค.

 

ํ”„๋กœ์ ํŠธ ๊ธฐ์ˆ  ์Šคํƒ

  • ํ”„๋ก ํŠธ์—”๋“œ: ํผ๋ธ”๋ฆฌ์‹ฑ์— JavaScript๋ฅผ ๋ง๋ถ™์—ฌ Ajax ์š”์ฒญ
  • ๋ฐฑ์—”๋“œ: Spring Boot, Spring Security, JDBC Template, Thymeleaf
  • DB: MySQL
  • ๋นŒ๋“œ: Maven
  • API ๋ฌธ์„œ: Rest Docs

๊ตฌํ˜„ํ•œ ๊ธฐ๋Šฅ์€ ํฌ๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์‚ฌ์šฉ์ž, ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€/๋‹ต๊ธ€, ๊ด€๋ฆฌ์ž CRUD 
  • ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง•, ๊ฒ€์ƒ‰, ์ถœ๋ ฅ ๊ฑด์ˆ˜ ์กฐ๊ฑด

๋™์˜์ƒ 1๊ณผ 2๋Š” ๊ฒฐ๊ณผ๋ฌผ์ด๋‹ค.

๋™์˜์ƒ 1. ๊ฒŒ์‹œํŒ ํ™ˆ ํ™”๋ฉด

 

๋™์˜์ƒ 2์˜ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋Š” ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ๋ชจ๋“  ๋Œ“๊ธ€/๋‹ต๊ธ€์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ˆ˜์ •์€ ๋ถˆ๊ฐ€ํ•˜๋‹ค.

๋™์˜์ƒ 2. ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ ํ™”๋ฉด

1. ์ฝ”๋”ฉ์€ ์˜ˆ์ˆ ์ด ์•„๋‹Œ ๋ฌธ์ œ ํ•ด๊ฒฐ์˜ ์ˆ˜๋‹จ

โ€œ๋Œ“๊ธ€๊ณผ ๋‹ต๊ธ€์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ์„ธ์š”.โ€ ๊ณผ์ œ์˜ ์š”๊ตฌ์‚ฌํ•ญ์€ ๊ฐ„๋‹จํ–ˆ์ง€๋งŒ, ๋‚˜๋Š” ์—ฌ๊ธฐ์— โ€˜๋ฌดํ•œ Depth ๋Œ€๋Œ“๊ธ€โ€™์„ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ตฌํ˜„ํ•˜๊ธฐ ๊ฐ€์žฅ ์–ด๋ ค์šธ ๊ฒƒ ๊ฐ™์•˜๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ๋Œ“๊ธ€ ํ…Œ์ด๋ธ”์— parent_id ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•˜๊ณ , ํ•ด๋‹น ๊ฒŒ์‹œ๊ธ€์— ํฌํ•จ๋œ ๋Œ“๊ธ€์„ ๊ฐ€์ ธ์˜จ ๋’ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์—์„œ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๋งŒ๋“  ํ›„ ์žฌ๊ท€์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜์—ฌ ๋Œ€๋Œ“๊ธ€์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

 Map<Integer, List<CommentResponse>> commentTreebyParentId = comments.stream()
                .collect(Collectors.groupingBy(
                        rep -> rep.replyParentId() == null ? TREE_ROOT : rep.replyParentId(),
                        LinkedHashMap::new,
                        Collectors.toList()
                ));

private static void visitCommentTree(List<CommentTreeResponse> treeResult, Map<Integer, List<CommentResponse>> byParentId, List<CommentResponse> comments, int depth) {
        if (comments == null) return; // ๋‹ค์Œ ๋…ธ๋“œ ์—†์œผ๋ฉด ์ข…๋ฃŒ
        comments.forEach(each -> {
            treeResult.add(CommentTreeResponse.of(each, depth));
            visitCommentTree(treeResult, byParentId, byParentId.get(each.commentId()), depth + 1);
        });
    }

 

๊ทธ๋ ‡๊ฒŒ ๊ธฐ๋Šฅ์„ ์™„์„ฑํ•œ ํ›„, "๋ฌดํ•œ Depth ๋กœ ๋Œ“๊ธ€์„ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ ๊ดœ์ฐฎ๊ฒ ์ฃ ?" ๋ผ๊ณ  ๋ฌผ์–ด๋ดค๋‹ค.

โ€œ์ด ๊ฒŒ์‹œํŒ์— ๋ฌดํ•œ Depth์˜ ๋Œ€๋Œ“๊ธ€์ด ์ •๋ง ํ•„์š”ํ•œ๊ฐ€์š”?โ€. ๊ทธ์ œ์„œ์•ผ ๋‚˜๋Š” 'ํ•˜๊ณ  ์‹ถ์€ ๋Œ€๋กœ' ๊ตฌํ˜„ํ–ˆ์ง€, ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ๊ฒƒ์„ ๊ตฌํ˜„ํ•˜์ง€๋Š” ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜๋‹ค.

์š”๊ตฌ์‚ฌํ•ญ์ด ๋ชจํ˜ธํ–ˆ๋˜๋งŒํผ ์ž์œจ์„ฑ์ด ์ปธ์ง€๋งŒ, ๋‚˜๋Š” "์š”๊ตฌ์‚ฌํ•ญ์ด ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋ณ€๊ฒฝ๋˜๋Š” ์ฝ”๋“œ"๊ฐ€ ์•„๋‹Œ ํก์‚ฌ "ํ•™๊ต ๊ณผ์ œ"๋ฅผ ๋งŒ๋“ค์—ˆ๊ตฌ๋‚˜๋ฅผ ๊นจ๋‹ฌ์•˜๋‹ค. ์ฆ‰, ๊ณผ์ œ๋ฅผ ์ž˜ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ์–ด๋ ค์šด ๊ฒƒ์„ ํƒํ•œ ๊ฒƒ์ด์—ˆ๊ณ , ๋ณธ์งˆ์„ ์žŠ๊ณ ์žˆ์—ˆ๋‹ค.

 

์š”๊ตฌ์‚ฌํ•ญ์œผ๋กœ โ€œ๋‹ต๊ธ€์ด 2 depth์˜€์œผ๋ฉด ์ข‹๊ฒ ์–ด์š”โ€๋กœ ๋ฐ”๋€๋‹ค๋ฉด, ์ด ๋ฌดํ•œ Depth๋Š” ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ˜‘์—… ์ธก๋ฉด์—์„œ ๋ถˆํ•„์š”ํ•œ ๊ตฌํ˜„์ด์—ˆ๋‹ค.

ํ›„์— ๋‹ต๊ธ€์ด 1 depth ์ด๋„๋ก ๋ฆฌํŒฉํ† ๋ง ํ•˜์˜€๊ณ , depth๊ฐ€ ๋” ์ปค์งˆ ์ˆ˜ ์žˆ๊ฒŒ(ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•ด) ์ถ”๊ฐ€๋กœ ๋Œ“๊ธ€ ํ…Œ์ด๋ธ”์— depth ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•˜๋ฉฐ ๋งˆ๋ฌด๋ฆฌ ํ–ˆ๋‹ค. ์ฝ”๋”ฉ์€ ์˜ˆ์ˆ ์ด ์•„๋‹Œ ๋ฌธ์ œ ํ•ด๊ฒฐ์˜ ์ˆ˜๋‹จ์ด์—ˆ๊ณ , ๋‚˜์˜ ๋งˆ์Œ๊ฐ€์ง์„ ๋ฐ”๊พธ๊ฒŒ ๋œ ๊ฒฝํ—˜์ด์—ˆ๋‹ค.

๋Œ“๊ธ€(comment) ํ…Œ์ด๋ธ”

 

2. ๊ธฐ์ดˆ ์ฒด๋ ฅ CS

ํšŒ์‚ฌ ๋‚ด๋ถ€๋ง์— ๊ฒŒ์‹œํŒ์„ ๋ฐฐํฌํ•˜๋ฉด์„œ ์—ฌ๋Ÿฌ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , ๋‚ด๋ถ€๋ง ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์„ค๋ช…์„ ๋“ฃ๋Š” ๊ณผ์ •์—์„œ ๋„คํŠธ์›Œํฌ ์ง€์‹์ด ํฐ ๋„์›€์ด ๋˜์—ˆ๋‹ค. ๋˜ํ•œ, ํšŒ์‚ฌ์˜ ์ฃผ๋ ฅ ์ œํ’ˆ์ด Elasticsearch ๊ธฐ๋ฐ˜์ด๋ผ ์ด๋ฅผ ํ•™์Šต ์ค‘์ธ๋ฐ, Elasticsearch์˜ JVM ํž™ ๋ฉ”๋ชจ๋ฆฌ/GC ํŠœ๋‹, ๋””์Šคํฌ ๊ตฌ์กฐ, ๊ณ ๊ฐ€์šฉ์„ฑ์„ ์œ„ํ•œ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ ๋“ฑ ๊ธฐ์ˆ ์„ ์‘์šฉํ•˜๋ ค๋ฉด ์ข…ํ•ฉ์ ์ธ CS ์ง€์‹์ด ์š”๊ตฌ๋˜์—ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ, ํŒŒ์ผ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ๋ถ€์กฑํ•จ์„ ๋Š๊ปด ๊ณต๋ถ€ํ•  ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

3. ๊ฐœ๋… ๊ฐ์ฒด๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

ํ™ˆ ํ™”๋ฉด(๋™์˜์ƒ 1)์„ ๊ตฌ์„ฑํ•˜๋‹ค ๋ณด๋‹ˆ ์ ์  ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์กŒ๋‹ค. ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์„ ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•˜๋ฉด์„œ๋„, ์œ ์ง€๋ณด์ˆ˜ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ œ๋ฏธ๋‹ˆ๋‹˜์˜ โ€˜์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์ง€์† ์„ฑ์žฅ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•โ€™์˜, '๊ฐœ๋… ๊ฐ์ฒด' ๋ฅผ ๋„์ž…ํ•˜๊ณ  ๋ถˆํ•„์š”ํ•œ import ๋ฅผ ์ œ๊ฑฐํ•˜๋ ค ๋…ธ๋ ฅ ํ–ˆ์ง€๋งŒ ์ž˜ ์™€๋‹ฟ์ง€ ์•Š์•˜๋‹ค. ํŠนํžˆ ๋ทฐ(View) ์˜์—ญ์ด ๋ณต์žกํ•  ๋•Œ ๊ฐœ๋… ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€๊ฐ€ ์ž˜ ๋– ์˜ค๋ฅด์ง€ ์•Š์•˜๋‹ค. ์•ž์œผ๋กœ๋„ ๊ณ„์† ๊ณต๋ถ€ํ•˜๋ฉด์„œ, ์–ธ์  ๊ฐ€ ๊ฐœ๋… ๊ฐ์ฒด์ฒ˜๋Ÿผ ์œ ์ง€๋ณด์ˆ˜์™€ ํ™•์žฅ์ด ์‰ฌ์šด, ์ง€์†์ ์œผ๋กœ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค.

4. Maven ๋นŒ๋“œ ํˆด ํ•™์Šต

์ด์ „์— ์ง„ํ–‰ํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Gradle์„ ์‚ฌ์šฉํ•ด Rest Docs๋ฅผ ๋ฐฐํฌํ•œ ๊ฒฝํ—˜์ด ์žˆ์–ด โ€œ๋‚˜ Rest Docs ํ•  ์ค„ ์•Œ์•„!โ€๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ, ๋ง‰์ƒ Maven์œผ๋กœ ํ•˜๋ ค๋‹ˆ ๋‚ฏ์„ค์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” Maven ๋ฌธ๋ฒ•๊ณผ Asciidoctor ๋ฌธ๋ฒ•์„ ๊ณต์‹ ๋ฌธ์„œ ์ค‘์‹ฌ์œผ๋กœ ํ•™์Šตํ–ˆ๋‹ค. ๊ฐ•์˜์— ์˜์กดํ•˜์ง€ ์•Š๊ณ , ์ง์ ‘ ์„ค์ •ํ•˜๊ณ  ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฝ๊ณ  ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ–ˆ๊ณ , ๊ทธ ๊ฒฐ๊ณผ Maven pom์†์„ฑ๊ฐ’๋“ค๊ณผ Asciidoctor ์— ๋Œ€ํ•ด ํ•„์š”ํ•œ ๊ฐ’๋“ค์„ custom ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

5. ํŽ˜์ด์ง€ ๊ฐ์ฒด ๊ตฌํ˜„ํ•˜๊ธฐ

์ˆœ์ˆ˜ JDBC Template์„ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํŽ˜์ด์ง• ์ •๋ณด๋ฅผ ๋‹ด๋Š” Page ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ๊ณ , ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์ฒ˜์Œ ๋ฒ„์ „์ด์—ˆ๋‹ค.

public class Page

public static Page of(int totalPages, int currentPage) {
        if (totalPages == 0) {
            return empty();   ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์ด ๋‚ด๋ถ€์— ์ˆจ๊ฒจ์ ธ ์žˆ์Œ
        }
        return new Page(
                ...
        );
}

private static Page empty(){
	...
}

 

์ฒ˜์Œ์—” ์ด ๋ฐฉ์‹์ด ๊ฐ„๋‹จํ•ด ๋ณด์˜€์ง€๋งŒ, ๋ฌธ์ œ๋Š” Page๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ชฝ(Service)์—์„œ Page.of(0, 0)์ฒ˜๋Ÿผ '0'์ด๋ผ๋Š” ๋งค์ง ๋„˜๋ฒ„๋ฅผ ์ง์ ‘ ๋‹ค๋ค„์•ผ ํ–ˆ๋‹ค๋Š” ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด '0'์€ ์„œ๋น„์Šค์˜ ์ฑ…์ž„์ด ์•„๋‹ˆ์—ˆ๋‹ค.
โ€œํŽ˜์ด์ง€๊ฐ€ ์—†๋‹คโ€๋Š” ์˜๋ฏธ๋Š” Page ๊ฐ์ฒด์˜ ์ฑ…์ž„์ด์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด Page.empty() ๋ฉ”์„œ๋“œ๋ฅผ ๋ณ„๋„๋กœ ์ •์˜ํ•˜๊ณ , ๋‚ด๋ถ€์— ์ƒ์ˆ˜ NO_PAGE๋ฅผ ์„ ์–ธ์„ ํ†ตํ•ด SRP๋ฅผ ์ค€์ˆ˜ํ•˜๊ณ ์ž ๋…ธ๋ ฅํ–ˆ๋‹ค.

private static final int NO_PAGE = 0;

public static Page empty() {
        return new Page(NO_PAGE, NO_PAGE, false, false, NO_PAGE, NO_PAGE, false, false);
}

public static Page of(int totalPages, int currentPage) {
    return new Page(
            totalPages,
            currentPage,
            hasPrevPage(currentPage),                 // '<' ๋ชจ์–‘
            hasNextPage(totalPages, currentPage),     //  '>' ๋ชจ์–‘
            getStartPageOfCurrentBlock(currentPage),  //  10n + 1 ํŽ˜์ด์ง€
            getLastPageOfCurrentBlock(totalPages, currentPage),  // 10(n+1)ํŽ˜์ด์ง€
            hasPrevBlock(currentPage),                //  '<<' ๋ชจ์–‘
            hasNextBlock(totalPages, currentPage));   //   '>>' ๋ชจ์–‘
}

 

6. ๊ทธ ์™ธ์˜ ๊ฒƒ๋“ค

JavaScript๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ HTML ๊ตฌ์กฐ์—๋„ ์ต์ˆ™ํ•ด์กŒ๊ณ , ์ „๋ฐ˜์ ์œผ๋กœ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์‚ฌ์šฉ์—๋„ ์ต์ˆ™ํ•ด์กŒ๋‹ค. ์ด๋ฏธ ํ•˜๋‚˜์˜ ์–ธ์–ด๋ฅผ ์•Œ๊ณ  ์žˆ๋Š” ์ƒํƒœ์—์„œ ์ƒˆ๋กœ์šด ์–ธ์–ด๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ด ํฌ๊ฒŒ ์–ด๋ ต์ง€๋Š” ์•Š๋‹ค๋Š” ์ ๋„ ์ฒด๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋‹ค๋งŒ, ์ค‘๋ณต ์—†์ด ๊ฐ€๋…์„ฑ ์ข‹์€ JavaScript๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ๊นŒ์ง€๋Š” ์•„์ง ๊ฐˆ ๊ธธ์ด ๋ฉ€๋‹ค.

 

Security์˜ ๋‚ด๋ถ€ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•œ ๋’ค ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ, ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•ด ์ผ๋‹จ์€ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ฐพ์•„์„œ ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค. ๋‚ด๋ถ€ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๊ณ  ์ด๋ฅผ ์•Œ๊ณ ์ž ํ•˜๋Š”๋ฐ, ์ด๋ฒˆ์—๋Š” ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•ด์„œ ๊ตฌํ˜„์„ ๋จผ์ € ํ•ด์•ผํ–ˆ๋‹ค. ๋‚ด๋ถ€ ์›๋ฆฌ๋ฅผ ์•Œ๊ณ  ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ํ’ˆ์งˆ์ด ๋‹ฌ๋ผ์ง„๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ๋Š๋ ค์ง„๋‹ค. ์—ญ์‹œ ๊ฐœ๋ฐœ์€ trade-off ์˜ ์—ฐ์†์ด๋‹ค.   

 

์ˆœ์ˆ˜ JdbcTemplate์„ ์‚ฌ์šฉํ•˜๋ฉฐ DB ํ…Œ์ด๋ธ”์˜ ํ•„๋“œ๋ช…์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์—ˆ๋‹ค. 

 

๊ฒŒ์‹œํŒ์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ๊ณ , ๊ทธ ๊ณผ์ •๋“ค์„ ๊ธ€์— ๋‹ด๊ณ  ์‹ถ์—ˆ์ง€๋งŒ ๋‹ค ๋‹ด์ง€ ๋ชปํ•ด ์•„์‰ฌ์›€๋„ ๋‚จ๊ณ , ๋ง‰์ƒ ์“ฐ๊ณ  ๋‚˜๋‹ˆ ๋ณ„ ๊ฒƒ ์—†๋Š”๊ฒƒ ๊ฐ™๊ธฐ๋„ ํ•˜๋‹ค.. ใ…Ž ๊ทธ๋ž˜๋„ ์ •๋ฆฌ๋ผ๋„ ํ•ด์•ผ ๋‚˜์ค‘์— ํ›„ํšŒ๋ฅผ ์•ˆํ•จ์„ ์•Œ๊ธฐ์— ์ •๋ฆฌ~