Aisha
수강평 작성수
3
평균평점
5.0
블로그
전체 3
2024. 03. 09.
0
인프런 워밍업 스터디 클럽 0기 BE - 3주차 발자국
드디어.. 마지막 주차의 발자국을 써보려고 한다!! 잘 달려왔다ㅎㅁㅎ학습 내용 요약이번주에는 배포에 대해서 학습해보았다.배포를 하기 위해서는 우선 전용 컴퓨터가 필요하다.전용컴퓨터에서는 우리 컴퓨터에 있는 코드를 옮겨야 하고, 우리 컴퓨터에 세팅된 환경을 전용 컴퓨터에서도 동일하게 세팅해둬야한다.(mysql이나 java설치 등)Profile그래서 동일한 서버코드를 사용하더라도, 실행이 될 때 우리 컴퓨터의 mysql을 쓸지 전용컴퓨터의 mysql을 쓸지를 다르게 설정함에 따라서 테스트를 해본다던지.. 등등이 가능할거다. 이러한 역할을 하는게 profile이다.넷플릭스를 볼 때, 친구들이랑 넷플릭스를 공유하고 4명의 프로필을 다르게 설정해서, 같은 아이디로 접속해도 다른 프로필을 고르면 각각의 다른 알고리즘이 적용된 자신만의 넷플릭스를 이용할 수 있다.이처럼 profile을 쓰면 자신이 다르게 설정하고 싶은 게 무엇인지에 따라, 동일한 서버 코드를 우리컴퓨터 mysql, 전용 컴퓨터 mysql 이런식으로 분리해서 돌려볼 수 있다는 말이다.AWS의 EC2배포를 위해서 다양한 전용컴퓨터를 이용할 수 있는데, AWS의 ec2를 사용해보았다.ec2에 mysql 등을 설치하는 과정이 필요한데,,,정확한 에러메시지를 캡처해두진 않았으나 설치과정에서 오류가 나서 꽤 오랜시간을 애먹었다.그러다가 아마존 리눅스 버전에 따라 설치해야 하는 레포지토리 버전도 맞춰줘야 하는데,강의자료에 있는 것이 옛날 버전(?) 임을 알게 돼서 겨우 해결했다.알고보니 강의노트에 태현님이 써두셨는데, 미리 발견을 못해서.....ㅜㅜㅜㅜㅜ너무 슬펐지만어쨌든 혼자 찾아 해결한거에 의의를 두려고 한다.참고)https://jinhos-devlog.tistory.com/entry/MySQL-8-Community-Edition-%EC%84%A4%EC%B9%98-%EC%A4%91-%EC%98%A4%EB%A5%98Lombok프로젝트 진행하면서 디스코드 채널에 다른 분들이 하는 얘기를 보면 lombok이라는 단어가 종종 등장했었는데,이게 애당초 뭔지를 몰라서 그냥 내가 모르는게 많구나..했었다.근데 프로젝트 하면서 제일 많이 반복 작성했던게 생성자, getter (보일러 플레이트 코드)였는데 이거를 내가 굳이 작성하지 않아도 자동으로 생성해주는게 lombok 라이브러리임을 알게 되었다.사용방법은 lombok의존성을 추가하고,인텔리제이에서 플러그인을 추가한 후에 @Getter, @NoArgsConstructor @RequiredArgsConstructor이런 어노테이션을 추가해주기만 하면 된다.학습 회고진도나가는거에 급급해서 제대로 이해 못하고 넘어간 부분이 많은거 같은데, 이제 프로젝트도 끝났으니 빠르게 복습을 해보려고 한다. 복습하면서 제대로 이해하지 못하고 넘어갔던 개념들을 다시 자세히 살펴보고, 프로젝트를 만들어봐야지. 미션해결 과정 및 프로젝트 진행방식 등등은 아래 노션에 정리를 해두었다!!https://www.notion.so/2500eeec60d54407bb5431c48e3dcc94 미션 회고스터디를 3주가량 진행 하면서 다른 분들이랑 코드 리뷰도 해보고 싶고, 사이드 프로젝트도 해보고 싶었는데...내가 그 정도 수준이 아님을 알게되었다. 자바 기본도 제대로 다져놓지 않아서 모르는거 투성이였고기본 강의를 병행해가며 듣다보니 많이 벅찼던 것 같다. 그럼에도!! 객체지향 언어를 절차지향적으로 짜는게 스스로가한심하다가도..!!! 처음 외국어를 배우는것과 동일하게, 난 자바라는 언어를 안지 한달 정도 밖에 안됐고그 언어를 화려한 문법과 정돈된 글씨체로 쓰지는 못해도 내가 구현하고 싶은걸 어떻게든 이 언어를 써서 했다는거 자체에너무 큰 의의를 두고 싶고 스스로를 칭찬하고 싶다.모르는게 아는것보다 많은 지금이 어쩌면 제일 성장이 가파른 때일테니 성취감도 느껴져서 좋기도 하다!수료식 전 당장의 일주일 동안은 자바 기본강의 + 이 강의를 복습하며 응용해 나갈 계획이다.

2024. 03. 02.
0
인프런 워밍업 스터디 클럽 0기 BE - 2주차 발자국
강의 수강학습 내용 요약스프링 컨테이너클래스 안에 메소드를 생성해서 그것을 사용하기 위해선, 클래스를 "인스턴스화" 하는게 필요하다.인스턴스화 한다는 건 간단히 말해서 붕어빵 틀(클래스)을 가지고 붕어빵을 만드는 거다.지난 1주차에서는 UserController라는 클래스 안에서 api 진입지점으로 사용할 메소드들을 정의했었다. 그런데 강사님이 하라는대로 하긴했는데, 생각해보면 UserController를 인스턴스화 한적이 없다.또한 mysql db와의 연결을 위해 jdbcTemplate이라는걸 사용했었는데,이 템플릿을 파라미터로 가져와서 사용하려면 어딘가에서 jdbc템플릿이 정의되어있어야 할텐데그런걸 한 적도 없다.@RestController public class UserController { private final UserService userService; public UserController(JdbcTemplate jdbcTemplate) { this.userService = new UserService(jdbcTemplate); } } 여기서 나오는 개념이 바로 스프링 컨테이너다.@RestController의 역할은 크게 두 가지이다.UserController 클래스를 API의 진입 지점으로 등록UserController 클래스를 스프링 빈으로 등록이 스프링 빈이라는 것이 스프링 컨테이너와 관계가 있다.서버가 시작되면 자동으로 생성되는 것이 컨테이너 라는 건데, 이 컨테이너에스프링 빈으로 등록된 클래스가 들어가게 된다. 또한 그 클래스의 인스턴스화도 함께 이뤄진다. 서버 시작 -> 기본 스프링 빈 등록 -> 개발자 설정 스프링 빈 등록 -> 해당 클래스들에게 필요한 의존성들이 자동 설정 따라서 UserController를 인스턴스화 해주지 않아도 메소드를 사용할 수 있었던 거다.또한 jdbc템플릿도 이미 스프링 빈으로 등록되었기 때문에 우리가 따로 정의해놓지 않았지만사용이 가능했다. 스프링 빈으로 굳이 왜 등록할까?코드가 줄어드는 것 같다. -> 그닥 드라마틱하진 않다.다양한 장점들이 있겠지만, 그냥 코드를 직접 짜는 입장에서 봤을 때는 인스턴스화를 new로 일일히 해주는게 귀찮았는데 스프링 빈으로 등록하면, 그냥 생성자에서 불러주기만 하면 돼서 좋은 것 같다.Repository에 변경사항이 생겼다고 가정할 때, service단의 변경도 필수가 된다. -> 이건 사고다왜냐하면, 지금은 레포지토리를 부르는 게 한군데 밖에 없었지만 실제 현업에서는 레포지토리를 사용하는 코드 전부를 고쳐야 할 것이기 때문이다.스프링 빈으로 등록하면, 컨테이너가 "의존성 주입"을 통해 변경된 레포지토리를 "선택"하도록 할 수 있다. -> 아주 좋다.참고) 의존성 주입을 위한 어노테이션@Primary@Qualifier 참고) 스프링 빈 등록하는 어노테이션Repository : @RepositoryService : @Servicecontroller: @RestController문자열 sql 대신 JPA 사용하기문자열 sql을 작성한 후, jdbctemplate을 이용해 mysql로 쿼리를 날리는 방식이 나쁘지 않다. 그런데 실제로 코드 짜면서 느낀거지만, 쿼리 하나가 좀 길다보니 간혹 오타를 낼 때 오류 잡는게 귀찮았다.-> 실수를 런타임 때 발견하게 되어, 인지가 느리다.또 sql의 문법이 문제다. sql을 만든 회사에 따라서 문법이 다 조금씩 다른데,이럴일이 흔한지는 모르겠지만 Mysql을 쓰다가 갑자기 Mssql로 변경한다면지옥일거다.-> 문자열 sql 쿼리를 모두 수정하는 불상사가 발생테이블에 칼럼이 5개만 해도 헷갈리는데, 그 이상이라고 한다면 데이터 하나당 테이블 칼럼으로 매칭해주는게 복잡해진다.-> 귀찮고 복잡하다.그래서 우리는 문자열 sql 대신 JPA를 사용할 수 있다.JPA란 데이터를 영구적으로(영속성) 보관하기 위해 자바 진영에서 정해진 규칙이다. 쉽게 말해 이 JPA를 사용해 코드를 작성하면 객체와 관계형 db(mysql등등) 테이블을 짝지어 영구적으로 저장이 가능하다.JPA를 사용하는 과정최초에 JPA를 적용하기 위한 옵션 설정. jdbc사용을 위해 만들었던 application.yml 에 코드 추가.테이블에 매핑되는 객체를 만들기. @Entity,@Id,@Column등 어노테이션 사용.주의) 기본 생성자 추가.인터페이스를 만들고, jpaRepository를 상속받게 한다. 테이블의 매핑 객체와, 테이블 id의 타입을 넣어준다.public interface UserRepository extends JpaRepository { } 우리가 만든 인터페이스는 jparepository를 상속받았기 때문에, save나 findAll 등 기본 내장 메소드를 쓸 수 있다. 기본 메소드 외에 쓰고 싶으면, 이 인터페이스에 추가를 해주자. 회고 : 모든 개념을 공부할 때는 굳이?왜? 라는 의문을 가져봐야 할 것 같다. 굳이 스프링 빈을 왜 쓰는지, 그냥 인스턴스화 시키는것보다 스프링빈으로 등록하는 장점은 무엇인지 등등 말이다.: 일단 기본적인 기능완성에 초점을 두고, 더 좋은 코드. 더 효율적인 코드를 고민해보면서 다양한 어노테이션을 제대로 이해해야 겠다.미션이번주 미션 해결 과정6일차 과제 1번 문제는 그냥 강사님 하신 코드 보고 그냥 똑같이 컨트롤러,서비스,레포지토리로 분류하는거라 간단히 해결했다.2번 문제도 mysql로 하는건 간단히 했던것 같은데, 오히려 그냥 리스트 객체로 레포지토리 만드는게 어려웠다.이 문제는 서비스단에, getFruit메소드와 memory레포지토리의 메소드가 핵심이였다.(지금 생각해보니 코드를 좀 이상하게 짠 것 같다.)- 메모리 레포지토리메모리 레포지토리의 getFruit메소드에서는 서버가 돌아가는동안 만들어진 과일 정보를 담은 fruits라는 리스트를 가지고 있는데,이 리스트를 돌며 과일의 이름을 가져와 사용자가 입력한 과일 이름이랑 일치하는 객체를 찾는다.일치할 경우 test라는 이름의 리스트에, 해당 객체의 가격정보와 판매여부를 담은 객체를 FruitResponse에서 받아와 저장한 후 이를 리턴한다.- 서비스단의 getFruit메소드이 리턴값을 fruitList에 받은 후, 리스트를 돌며 판매여부를 확인한 뒤 팔렸으면 salesTotal에, 안팔렸으면 notSalesTotal변수에 가격 정보를 누적하고 이를 객체로 감싸 반환하게 코드를 짰다.public FruitFinalResponse getFruit(String name){ //가져온 데이터 결과 rs 를 우리가 원하는 userResponse형태로 바꿔줌.이거는 객체 참조값인데, 전체에서 반환하는건 결국 query로 감싸서 나오므로 리스트 타입. boolean isFruitNameNotExist = fruitRepository.isFruitNameNotExist(name); if(isFruitNameNotExist){ throw new IllegalArgumentException(); }else{ List fruitList = fruitRepository.getFruit(name); long salesTotal=0; long notSalesTotal=0; for(int i=0; ipublic List getFruit(String name){ List test = new ArrayList(); for (Fruit fruit : fruits) { if(fruit.getFruitName().equals(name)) { FruitResponse fruitResponse = new FruitResponse(fruit.getPrice(),fruit.isSell()); test.add(fruitResponse); } } return test; } 7일차 과제1번 문제는 JPA를 활용하는 강사님 코드를 참고해서 쉽게 기존의 코드를 고쳐서 해결했다.2번 문제는 고민을 좀 했었는데, 다행히 기본 JPA메소드 중에 countByName이라는게 있었고 이걸 활용하면테이블에서 쿼리로 들어온 과일이름 (=name)을 기반으로 count를 해준다. public fruitNumResponse getFruitNum(String name){ return new fruitNumResponse(fruitRepository.countByName(name)); } 3번 문제는 쿼리로 들어온 option의 문자열을 가지고, if문 처리를 하는게 핵심이였다.찾아보니 findByPriceGreaterThanEqual,findByPriceLessThanEqual 요런 메소드들이 있어서 쉽게 데이터를 뽑을 수 있었다.(나중에 강사님 코멘트를 보니 enum이라는걸 활용하면 이렇게 문자열로 안해도 된다는데 확인해봐야겠다.) 그렇게 가져온 데이터들의 판매여부를 확인한 후, 판매되지 않은것만 가져와야 하기 때문에 false인 객체들만 notSellFruits에 담아 반환하도록 코드를 짰다.public List getFruitList(String option,Long price){ Collection fruits; if(option.equals("GTE")){ fruits = fruitRepository.findByPriceGreaterThanEqual(price); }else{ fruits = fruitRepository.findByPriceLessThanEqual(price); } List fruitList = fruits.stream(). map(fruit1 -> new FruitListResponse(fruit1.getName(), fruit1.getPrice(),fruit1.getWarehousingDate(),fruit1.isSell())) .collect(Collectors.toList()); List notSellFruits = new ArrayList(); for (FruitListResponse fruitListResponse : fruitList) { if(fruitListResponse.isSell()==false) { notSellFruits.add(fruitListResponse); } } return notSellFruits; } 미션 회고기억해야 할 오류1)자바의 카멜 표기법이 DB에서는 (언더바)로 변환된다는걸 몰라서 발생한 오류였다.warehousingDate이라는 변수명을 필드명으로 지정했었는데, 한참 오류가 떠서 구글링하다가 원인을 발견해서 mysql 칼럼명을 warehousing_Date으로 바꾸어 해결할 수 있었다.기억해야 할 오류2) query did not return a unique result: 2이 오류는 findByName을 할 때 데이터가 여러갠데 받아오는 리턴 타입이 문제여서 발생했다. 원래는 List으로 받았는데 Collection으로 고쳐서 해결됐다. 근데 나는 List랑 Collection차이를 모르니까 공부해야겠다...++ 미니 프로젝트 회고)바로바로 하려니까 헷갈려서, 엑셀에 필요 조건들이랑 스펙을 정리하고 코드를 짜는 중이다.그리고 생각보다 미니 프로젝트에 제시된 것만으로는 코드를 바로 짤 수가 없었던 것 같다. 어떤식으로 테이블을 구성할지, 또 어떤 정보들을 쿼리 또는 바디로 받아올지 등등 하나부터 열까지 내가 정해야 되니까좀 어렵긴 한데, 그래도 재밌다!!

2024. 02. 24.
0
인프런 워밍업 스터디 클럽 0기 BE - 1주차 발자국
강의 수강 내용1) 학습 내용 정리어노테이션 정리1) @RestController: 주어진 Class를 Controller로 등록할 때 사용 (Controller : API의 진입 지점 )❗전달되는 데이터는 쿼리와 body, 이렇게 두 가지를 통해 전달됨.2) @RequestParam: 주어지는 쿼리를 함수 파라미터에 넣는다.3) @RequestBody: 주어지는 body를 함수 파라미터에 넣는다.4) @GetMapping("/add"): 아래 함수를 HTTP메소드가 GET이고, PATH가 /add 인 API로 지정할 때 사용.* 메소드에 따라서 GET,POST,PUT,DELETE등 의 mapping이 있다. body에 데이터를 담는 방법 : JSON(객체를 표기하는 기법)👇 이렇게 다양한 타입의 데이터를 담아 객체로 전달할 수 있음{ "name": "아아아", "age": 99, "house": { "address": "대한민국 서울", "hasDoor": true } } ❗ 객체에 getter가 담겨 있으면, 반환할 때 JSON으로 응답이 나감.spring에서 데이터 베이스 사용하기Mysql에서 데이터를 변경하거나 가져오는 등을 수행하기 위해서는, sql쿼리를 활용해야 한다.spring에서 그러한 쿼리를 mysql로 날려주는 역할을 하는것이 jdbcTemplate이다. @RestController public class UserController { private final JdbcTemplate jdbcTemplate; public UserController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @PostMapping("/user") public void saveUser(@RequestBody UserCreateRequest request) { String sql = "INSERT INTO user(name, age) VALUES(?, ?)"; jdbcTemplate.update(sql, request.getName(), request.getAge()); } } 위 예시 코드를 보면, sql 스트링 변수를 만들어 쿼리를 저장했다.쿼리를 보면 값이 들어가야 할 자리를 ? 물음표로 넣는다.jdbcTemplate.update는 sql에서 말하는 update를 의미하는게 아니고, 데이터 입력(INSERT),변경(UPDATE),삭제(DELETE)든 간에update라는 메소드를 쓰는거다.맨 앞의 인자에는 mysql로 날릴 쿼리를 입력하고, 이후 인자들에는 물음표에 들어갈 값들을 입력해주면 된다.❗주의할 점은, SELECT만 jdbcTemplate.query 를 사용한다는 거다.2) 나에게 피드백-> 이번 주 잘한 점: 사실 이 스터디 신청한게 내 수준보다 좀 너무 높아서 문제였다. 자바 기초 문법만 공부하고 이걸 신청했는데, 생성자, getter, 객체 지향,, 클래스, 인스턴스 등등 모르는 개념이 너무 많아서 그냥 포기하려고 했다.하지만 완주를 못하더라도 여기서 나오는 개념들을 그때그때 공부해서라도 따라가자는 생각에, 다른 자바 기본 강의를 병행하면서 내가 몰랐던 개념들을 학습해가며 미션을 수행했다.결론적으로는 미션은 어느정도 잘하고 있다!!! 그래도 아직 모르는게 산더미라서..다음주부터는 발자국에다가 그날그날 배운거를 바로 정리하는 용으로 쓰면서 복습을 해야겠다.미션: 미션 풀이미션 1: 어노테이션이 무엇이고, 어노테이션을 만드는 방법에 대한 과제였다.나는 어노테이션이라는 개념 자체가 너무 생소하기 때문에, 다양한 어노테이션들이 있지만우선 강의에서 다뤘던 어노테이션들이 하는 역할에 대해 주로 정리했다.https://velog.io/@aisha00/인프런-워밍업-스터디-클럽-0기-BE-1일차-과제미션 2: 우리는 GET API와 POST API를 다루는 과제였다.1번은 요청 값을 가지고 여러가지 연산을 수행해야 했기 때문에, 데이터를 받아오는 객체를 따로 만들어거기서 연산을 수행하고 받아오는 식으로 코드를 짰다.2번은 date값 한개만 쿼리로 가져오기 때문에, RequestParam 을 사용해 값을 바로 받아와서 문제를 해결했다.3번은 요청을 받는 DTO에 리스트가 있으면 json을 받아올 수 있다는 힌트가 없었다면 못 풀뻔 했다. 아무튼 DTO를 만들어서 받아온 리스트 데이터를 리턴하고, 그 값을 for문을 돌려 누적합을 계산했다.https://velog.io/@aisha00/인프런-워밍업-스터디-클럽-0기-BE-2일차-과제미션 3:람다식과 익명클래스에 대한 과제였다.자바 문법도 잘 몰라서, gpt한테 람다식이 뭔지 익명클래스가 뭔지 진짜 상세하게 물어보니까 잘 알려줬다.그러나 아직도 와닿는 개념은 아니여서 공부가 더 필요할 것 같다.https://velog.io/@aisha00/인프런-워밍업-스터디-클럽-0기-BE-3일차-과제미션 4:mysql과 spring을 연동해 데이터를 다루는 api 과제였다.2번은 그냥 id값만 문제에 나와있어서 어떤걸 해야 하는 과제인건지 처음에 헤맸는데, db자체에 판매여부를 기록하는 칼럼이 있어야 할거 같아서 그것부터 테이블에 추가했다.id를 받아서 isSell이라는 boolean타입의 판매여부 칼럼을 변경해주는 식으로 해결했다.https://velog.io/@aisha00/인프런-워밍업-스터디-클럽-0기-BE-4일차-과제미션 5:제일 난해했던 과제였다. 뭔가 4번이랑 비슷한 맥락으로 내가 문제이해를 잘 못해서 헤맸던 것 같다.문제에서 요구하는건 특정 과일이 판매된건 총 얼마고, 판매 안된건 총 얼마냐 이거를 알려달라는건데나는 판매되지 않은 과일의 가격에는 어떤게 있고, 안 팔린거는 어떤게 있는지를 각각 리스트로 담아달라는 줄 알았다.한참 고민하다가 뒤늦게 문제를 잘못 이해했음을 깨닫고,,,,특정 과일에 대한 모든 정보를 List로 담아온 후, isSell 변수의 값을 확인해 팔린 과일의 총합과 팔리지 않은 과일의 총합을 나누어 누적값을 계산 했다.https://velog.io/@aisha00/인프런-워밍업-스터디-클럽-0기-BE-5일차-과제 : 미션 수행 시 느낀점1. 나는 감자다🥔아무래도 제출에 급급하다보니, 강의해서 나온 방식을 그냥 그대로 따라하는 경향이 있었던 것 같다.예를 들어, 받아오는 데이터가 한 갠데 굳이 객체로 감싸오는 과정을 추가하는 등 불필요한 클래스를 만들어해결하려고 했던 접근 방식이 있었던 것 같다.전반적으로 이해가 부족해서 그런 것 같은데, 코드를 다시 찬찬히 뜯어보면서 왜 굳이 이 코드를 작성했는가에 대한 의문을 품고 문제를 해결할 필요가 있어 보인다.2. 나는 냅다 자꾸 문제에 머리부터 들이미는 경향이 있다.오래걸렸던 문제를 생각해보면, 문제 이해를 애초에 대충하고 문제부터 풀려고 했던게 요인이였다.실무에서 제일 중요한건 코드를 잘 짜는것도 맞지만, 요구사항에 맞는 코드를 짜지 않으면 아무 소용이 없다.제일 중요한 걸 간과했던 거 같아서 다음주부터는 과제의 요구사항을 세심하게 이해하는 걸 명심해야겠다.




