ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [๊ฐ•์˜] ์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB์ ‘๊ทผ ๊ธฐ์ˆ  2
    SPRING/INFLEARN 2021. 4. 5. 05:53

    ์Šคํ”„๋ง ๊ณต๋ถ€~

    inf.run/reCZ

     

    [๋ฌด๋ฃŒ] ์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

    ์Šคํ”„๋ง ์ž…๋ฌธ์ž๊ฐ€ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€๋ฉด์„œ ์Šคํ”„๋ง ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ์ „๋ฐ˜์„ ๋น ๋ฅด๊ฒŒ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., ์Šคํ”„๋ง ํ•™์Šต ์ฒซ ๊ธธ์žก์ด! ๊ฐœ๋ฐœ ๊ณต๋ถ€์˜ ๊ธธ์„ ์žƒ์ง€ ์•Š๋„๋ก ๋„์™€๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๐Ÿ“ฃ ํ™•์ธํ•ด์ฃผ์„ธ

    www.inflearn.com

    ๋ฌด๋ฃŒ๋ถ€๋ถ„๋งŒ ์˜ฌ๋ฆฌ๊ฒ ์Œ

    ์ถœ์ฒ˜ : inf.run/reCZ ๊ฐ•์˜

     

    3. ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ

    - ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ ์ •๋ฆฌ

    ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๊ฐ€ ์„ ์ •๋˜์ง€ ์•Š์Œ์„ ๊ฐ€์ •

    ์ปจํŠธ๋กค๋Ÿฌ → ์„œ๋น„์Šค → ๋ฆฌํฌ์ง€ํ† ๋ฆฌ → DB

              โ†˜      ↓        โ†™

                     ๋„๋ฉ”์ธ

    ์„œ๋น„์Šค : ํšŒ์› ์ค‘๋ณต ๊ฐ€์ž…์ด ์•ˆ๋œ๋‹ค ๊ฐ™์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง

               ๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋Œ์•„๊ฐ€๋„๋ก ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด

    ๋ฆฌํฌ์ง€ํ† ๋ฆฌ : ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ณ 

    ๋„๋ฉ”์ธ : ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ ๊ฐ์ฒด

     

    ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ตฌํ˜„์ฒด๋กœ ๋งŒ๋“ค์–ด์„œ ๋‚˜์ค‘์— ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ์„ ์ • ํ›„ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„

     

     

    - ํšŒ์› ๋„๋ฉ”์ธ๊ณผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

     

    //Member.java - member ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ
    public class Member {
    
        private Long id;//id ์‹๋ณ„์ž, ์‹œ์Šคํ…œ์ด ์ž๋™ ์ €์žฅ
        private String name;//์ด๋ฆ„
    
        public Long getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    //MemberRepository.java
    public interface MemberRepository {
        Member save(Member member);
        Optional<Member> findById(Long id); //id๋กœ ํšŒ์› ์ฐพ๊ธฐ
        Optional<Member> findByName(String name); //์ด๋ฆ„์œผ๋กœ ํšŒ์› ์ฐพ๊ธฐ
        //Optional -> null๋กœ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฑฐ ๋ฐฉ์ง€
        List<Member> findAll();
    }
    //MemoryMemberRepository.java
    public class MemoryMemberRepository implements MemberRepository {
    
        private static Map<Long, Member> store = new HashMap<Long, Member>();
        private static long sequence = 0L; //key๊ฐ’ ์ƒ์„ฑ
    
        @Override
        public Member save(Member member) {
            member.setId(++sequence);//id ๋Š” ์‹œ์Šคํ…œ์ด ์ •ํ•ด์ค€๋‹ค.
            store.put(member.getId(), member);
            return member;
        }
    
        @Override
        public Optional<Member> findById(Long id) {
            return Optional.ofNullable(store.get(id));
        }
    
        @Override
        public Optional<Member> findByName(String name) {
            return store.values().stream()
                    .filter(member -> member.getName().equals(name))
                    .findAny(); //  map์— ์ด๋ฆ„์ด ํ•˜๋‚˜๋ผ๋„ ์žˆ์œผ๋ฉด ๋ฐ˜ํ™˜. ์—†์œผ๋ฉด null์ด ํฌํ•จ๋˜์„œ ๋ฐ˜ํ™˜
        }
    
        @Override
        public List<Member> findAll() {
            return new ArrayList<>(store.values());
        }
    }

     

    - ํšŒ์› ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ

    JUnit์ด๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ํ…Œ์ŠคํŠธ ์‹คํ–‰

    //MemoryMemberRepositoryTest.java
    public class MemoryMemberRepositoryTest {
        MemoryMemberRepository repository = new MemoryMemberRepository();
    
        @AfterEach //๋งค๋ฒˆ ๋๋‚ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ํ•˜๊ฒŒ ํ•˜๋Š” ์ฝœ๋ฐฑ ๋ฉ”์†Œ๋“œ
        public void afterEach(){
            repository.clearStore();
        }
    
        @Test
        public void save(){
            Member member = new Member();
            member.setName("spring");
            repository.save(member);//๋ฉค๋ฒ„ ์ €์žฅ
            Member result = repository.findById(member.getId()).get(); //์ €์žฅํ•œ ๋ฉค๋ฒ„ ์ฐพ๊ธฐ
            //optional์—์„œ๋Š” get์œผ๋กœ ๋ฐ”๋กœ ๊บผ๋‚ผ ์ˆ˜ ์žˆ์Œ(์ข‹์€ ๋ฐฉ๋ฒ• x)
            //1)System.out.println("Result = " + (result == member));
            //2)Assertions.assertEquals(member, null);
            //3)
            assertThat(member).isEqualTo(result);
        }
    
        @Test
        public void findByName(){
            Member member1 = new Member();
            member1.setName("spring1");
            repository.save(member1);
    
            Member member2 = new Member();
            member2.setName("spring2");
            repository.save(member2);
    
            Member result = repository.findByName("spring1").get();
            assertThat(result).isEqualTo(member1);
        }
    
        @Test
        public void findAll(){
            Member member1 = new Member();
            member1.setName("spring1");
            repository.save(member1);
    
            Member member2 = new Member();
            member2.setName("spring2");
            repository.save(member2);
    
            List<Member> result  = repository.findAll();
            assertThat(result.size()).isEqualTo(2);
        }
    
        //์ˆœ์„œ๋Š” ๋ณด์žฅ ํ•  ์ˆ˜ ์—†๋‹ค. ์•ž์—์„œ ํ…Œ์ŠคํŠธ ํ•œ๋ฒˆ์ด ๋๋‚˜๊ณ  ๋‚˜๋ฉด clear๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
        //-> ์ˆœ์„œ๊ฐ€ ์ƒ๊ด€ ์—†๊ฒŒ ๋งŒ๋“ค์ž
    
    }
    

    ์ž˜๋จ ํ‚ค์—จ

    - ํšŒ์› ์„œ๋น„์Šค ๊ฐœ๋ฐœ

    //MemberService.java
    public class MemberService {
        private final MemberRepository memberRepository = new MemoryMemberRepository();
        //ํšŒ์›๊ฐ€์ž…
        public Long join(Member member){
            //๊ฐ™์€ ์ด๋ฆ„ ์ค‘๋ณตํšŒ์› x
           validateDuplicateMember(member);
            memberRepository.save(member);
            return member.getId();
        }
    
        private void validateDuplicateMember(Member member){
            memberRepository.findByName(member.getName())
                    .ifPresent(m->{
                        throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
                    });
        }
    
        //์ „์ฒด ํšŒ์› ์กฐํšŒ
        public List<Member> findMembers(){
            return memberRepository.findAll();
        }
    
        //id๋กœ ์‚ฌ๋žŒ ์ฐพ๊ธฐ
        public Optional<Member> findOne(Long memberID){
            return memberRepository.findById(memberID);
        }
    }

     

    - ํšŒ์› ์„œ๋น„์Šค ํ…Œ์ŠคํŠธ

    <<๋‹จ์ถ•ํ‚ค>>

    ctrl+shift+t -> test class ๋งŒ๋“ค์–ด์ค€๋‹ค

    ctrl+alt+v -> Optional๋กœ ๊ฐ์‹ธ๊ธฐ/reCZ

    shift+F10 -> ์‹คํ–‰

    //MemberServiceTest.java
    class MemberServiceTest {
    
        MemberService memberService;
        MemoryMemberRepository memberRepository;
    
        @BeforeEach
        public void beforeEach(){
            memberRepository = new MemoryMemberRepository();
            memberService = new MemberService(memberRepository);
        } // -> DI
        @AfterEach
        public void afterEach(){
            memberRepository.clearStore();
        }
    
        @Test
        void ํšŒ์›๊ฐ€์ž…() { //ํ•œ๊ธ€๋กœ ํ•ด๋„ ๋œ๋‹ค!
            //given ์ƒํ™ฉ์ด ์ฃผ์–ด์ง
            Member member = new Member();
            member.setName("spring");
    
            //when ์ด๊ฑธ๋กœ ์‹คํ–‰ํ•จ
            Long saveId = memberService.join(member);
    
            //then ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ด
            Member findMember = memberService.findOne(saveId).get();
            assertThat(member.getName()).isEqualTo(findMember.getName());
         }
        @Test
        public void ์ค‘๋ณต_ํšŒ์›_์˜ˆ์™ธ(){
            //given
            Member member1 = new Member();
            member1.setName("spring");
            Member member2 = new Member();
            member1.setName("spring");
    
            //when
            memberService.join(member1);
            /*1)
            try {
                memberService.join(member2);
                fail(); //fail์—์„œ ๊ณ„์† ์˜ค๋ฅ˜๋‚จ ์ด์œ  ์•Œ์•„๋‚ผ ๊ฒƒ
            }catch(IllegalStateException e){
                assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
            }*/
            //2)
            IllegalStateException e = assertThrows(IllegalStateException.class,
                    () -> memberService.join(member1));
    
            //then
    
        }
    
        @Test
        void findMembers() {
        }
    
        @Test
        void findOne() {
        }
    }

     

     

    ๋„˜ ์–ด๋ ต๋‹ค... ๋‹ค์‹œ ๊ณต๋ถ€ํ•ด์•ผํ• ๋“ฏ

    4. ์Šคํ”„๋ง ๋นˆ๊ณผ ์˜์กด ๊ด€๊ณ„

    - ์ปดํฌ๋„ŒํŠธ ์Šค์บ”๊ณผ ์ž๋™ ์˜์กด๊ด€๊ณ„ ์„ค์ •

    ์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก

       1) ์ปดํฌ๋„ŒํŠธ ์Šค์บ”, ์ž๋™ ์˜์กด ๊ด€๊ณ„ ์„ค์ • (@Component๋ฅผ ํฌํ•จํ•˜๋Š” ์• ๋…ธํ…Œ์ด์…˜)

       ์Šคํ”„๋ง์€ ์ปดํฌ๋„ŒํŠธ ์• ๋…ธํ…Œ์ด์…˜(@)์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•œ๋‹ค.

       @AutoWired๋Š” ์–˜๋„ค๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์„  ๊ฐ™์€ ๋А๋‚Œ

       ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ•˜๋‚˜์”ฉ๋งŒ ๋“ฑ๋กํ•ด ์‚ฌ์šฉํ•œ๋‹ค.(์‹ฑ๊ธ€ํ†ค) ์„ค์ • ๊ฐ€๋Šฅ ํ•˜๊ธด ํ•˜์ง€๋งŒ ์›ฌ๋งŒํ•˜๋ฉด ์‹ฑ๊ธ€ํ†ค

       DI์—๋Š” ํ•„๋“œ ์ฃผ์ž…, setter ์ฃผ์ž…, ์ƒ์„ฑ์ž ์ฃผ์ž… 3๊ฐ€์ง€ ๋ฐฉ๋ฒ• -> ์ƒ์„ฑ์ž ์ฃผ์ž… ๊ถŒ์žฅ

    MemberController -> MemberService -> MemberRepository

    //MemberController.java
    @Controller
    public class MemberController {
        private final MemberService memberService; //= new MemberService(); ์—ฌ๋Ÿฌ๊ฐœ ์“ฐ๋Š” ๊ฑด ์˜๋ฏธ๊ฐ€ ์—†์Œ
    
        @Autowired
        public MemberController(MemberService memberService) {
            this.memberService = memberService;
        }
    }
    

       2) ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ง์ ‘ ์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก

       ๋‹ค์Œ์— ๋‚˜์˜ด

     

    - ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ง์ ‘ ์Šคํ”„๋ง ๋นˆ ๋“ฑ๋กํ•˜๊ธฐ

    @Configuration
    public class SpringConfig {
        @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
        @Bean
        public MemberRepository memberRepository() {
            return new MemoryMemberRepository();
        }
    }

     

    5. ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - ์›น MVC ๊ฐœ๋ฐœ

    - ํšŒ์› ์›น ๊ธฐ๋Šฅ - ํ™ˆ ํ™”๋ฉด ์ถ”๊ฐ€

    //HomeController
    @Controller
    public class HomeController {
    
        @GetMapping("/") //์šฐ์„  ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— index.html ๋ฌด์‹œ
        public String home(){
            return "home";
        }
    
    }

    ์‹คํ–‰

    - ํšŒ์› ์›น ๊ธฐ๋Šฅ - ๋“ฑ๋ก

    //MemberForm.java
    public class MemberForm {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    //MemberController.java
    @Controller
    public class MemberController {
        private final MemberService memberService; //= new MemberService(); ์—ฌ๋Ÿฌ๊ฐœ ์“ฐ๋Š” ๊ฑด ์˜๋ฏธ๊ฐ€ ์—†์Œ
    
        @Autowired
        public MemberController(MemberService memberService) {
            this.memberService = memberService;
        }
    
        @GetMapping("/members/new")
        public String createForm(){
            return "members/createMemberForm";
        }
        @PostMapping("/members/new")
        public String create(MemberForm form){
            Member member = new Member();
            member.setName(form.getName());
    
            memberService.join(member);
            System.out.println(member.getName());
            return "redirect:/";
        }
    }

    ์ž˜ ๋‚˜์˜จ๋‹ค. ๊น€์ฒ ์ˆ˜๋ฅผ ์ž…๋ ฅํ•ด ๋ณด์•˜๋‹ค.

     

    System.out.println(member.getName());์„ ์ถ”๊ฐ€ํ•œ ํ›„ ๊ฒฐ๊ณผ ์•„์ฃผ ๋‚˜์ด์Šค

    - ํšŒ์› ์›น ๊ธฐ๋Šฅ - ์กฐํšŒ

     

    //MemberController.java ์˜ ์ผ๋ถ€
    @GetMapping(value = "/members")
        public String list(Model model) {
            List<Member> members = memberService.findMembers();
            model.addAttribute("members", members);
            return "members/memberList";
        }

    ํšŒ์› ๊ฐ€์ž…์‹œํ‚จ 3๋ช…์„ ๋ชฉ๋ก์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

     

Designed by Tistory.