논빈
수강평 작성수
-
평균평점
-
블로그
전체 3#카테고리
- 백엔드
#태그
- 인프런워밍업클럽1기BE
![[인프런 워밍업 클럽 스터디]BE 1기 세번째 발자국](https://cdn.inflearn.com/public/files/blogs/ee0f91ef-6966-424c-9df7-965d21eead46/fdd.png?w=260)
2024. 05. 19.
0
[인프런 워밍업 클럽 스터디]BE 1기 세번째 발자국
어째 계속 변명 회고가 되어가고 있는데 호기롭게 다짐한 것과 달리 공부를 많이 못했다. 지금 이후부터 담주까지 열심히 강의를 들어 완주하는 것에 만족하려고 한다. ㅜㅜ 아직도 10일차에 머물러 있지만 금방 완주할 수 있을거다!! Section4섹션4에서는 JPA를 다루는 방법에 대해 배운다. 문자열 SQL을 직접 사용하는 것의 한계문자열을 작성하기 때문에 실수할 수 있고, 실수를 인지하는 시점이 느림 // 유저 조회 public List getUsers() { String sql = "SELECT * FROM user"; return jdbcTemplate.query(sql, (rs, rowNum) -> { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); }); } String sql = "SELECT * FROM user"; 이 부분에 실행이 되지 않아도 빨간줄이 안 뜸⇒ 오류가 컴파일 시점에 발견되 지 않고, 런타임 시점에 발견됨 ( 컴파일 : 서버를 실행할때 자바 코드를 .class 코드로 변화시켜서 jvm에서 동작시켜야하는 과정) ( 런타임 : 실제 서버가 가동된 이후)특정 데이터베이스에 종석적이게 됨다른 db로 바꾸려면 전체를 바꿔야 하는 어려움반복 작업이 많아짐, 테이블을 하나 만들 때마다 CRUD 쿼리가 항상 필요데이터베이스의 테이블과 객체는 패러다임이 다름부모 클래스와 하위 클래스들을 구분짓기 어려움JPA란?Java Persistence API ( 자바 영속성 API ) ⇒ 자바 진영의 ORM(Object - Relational Mapping)Java Persistence API ( 자바 영속성 API )영속성 : 서버가 재시작되어도 데이터는 영구적으로 저장되는 속성API : 정해진 규칙⇒ 데이터를 영구적으로 보관하기 위해 자바 진영에서 정해진 규칙 ORM(Object - Relational Mapping)Object : 객체Relational : 관계형 db⇒ 관계형 db의 테이블Mapping : 객체랑 테이블을 연결 즉, JPA란 ?객체와 관계형 db의 테이블을 짝지어 데이터를 영구적으로 보관하기 위해 Java 진영에서 정해진 규칙말로 되어있는 규칙을 코드로 표현 → HibernateHibernate(구현체) → 구현(implement) → JPA ⇒ 즉, JPA는 interface(규칙)이고, Hibernate는 그것을 구현하는 구현체며 JDBC를 사용한다. 다음 강의에서는 User 객체에 엔티티를 넣는 방법을 배운다.사실 객체에 @Entity 를 적어주면 된다.@Entity public class User { @Id // id라는 걸 알리기 위해 => primary @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id = null; @Column(nullable = false, length = 20) // name(varchar) = 20 private String name; private Integer age; }@Entity : 스프링이 User객체와 user 테이블을 같은 것으로 바라봄entity의 의미 ⇒ 데이터베이스에서 저장되고, 관리되어야 하는 데이터 id에 auto_increment 가 있으므로@GeneratedValue(strategy = GenerationType.*IDENTITY*) 로 자동 생성되는 값임을 명시@id : 이 필드를 primary key로 간주함@GeneratedValue : primary key는 자동 생성되는 값임 @Column : 객체의 필드와 Table의 필드를 매핑함null이 들어갈 수 있는지의 여부, 길이 제한, db에서의 column 이름 등등이 들어감 매핑은 끝 → JPA를 사용하니 추가적인 설정을 해주어야 함application.yml jpa: # hibernate: ddl-auto: none # 우리 프로젝트는 테이블과 객체가 잘 연결되었기 때문에 필요 X properties: hibernate: show_sql: true # JPA를 사용해 db에 Sql을 날릴 때 Sql을 보여줄지에 관한 것 format_sql: true # sql을 보여줄 때 예쁘게 포맷할 것인지 dialect: org.hibernate.dialect.MySQL8Dialect # 이 옵션으로 db를 특정하면 조금씩 다른 Sql을 수정 Spring에 jpa-hobernate-ddl-auto라는 옵션이 있는데 이 옵션은 스프링이 시작할때 디비에 있는 테이블을 어떻게 처리할지에 관함→ 테이블이랑 객체랑 다름(매핑을 잘못함)일 때 어떻게 할지에 대한 옵션ddl-auto: create : 기존 테이블이 있다면 삭제 후 다시 생성ddl-auto: create-drop : 스프링이 종료될 때 매핑됐던 테이블 모두 제거ddl-auto: update : 객체와 테이블이 다른 부분만 변경ddl-auto:validate : 객체와 테이블이 동일한지 확인ddl-auto: none : 별다른 조치 X Spring Data JPA를 이용해 자동으로 쿼리 날리는 방법에 대해 배운다.⇒ sql을 작성하지 않고 유저 생성/ 조회/ 업데이트 기능 리팩토링 유저 생성 기능UserServiceV2@Service public class UserServiceV2 { private final UserRepository userRepository; public UserServiceV2(UserRepository userRepository) { this.userRepository = userRepository; } // 이미 UserRepository에서 JPA를 상속받기 때문에 그냥 불러와서 public void saveUser(UserCreateRequest request){ userRepository.save(new User(request.getName(), request.getAge())); } // save 함수만 써주면 저장됨 => 이미 있는 문법(sql문이 필요없다) // User -> JPA로 되어있는 객체 } save 메소드에 객체를 넣어주면 INSERT SQL이 자동으로 날라감save되고 난 후 유저는 id를 갖게 됨 유저 조회 기능유저 조회 기능UserServiceV2// 유저 조회 public List getUsers(){ return userRepository.findAll().stream() // 모든 테이블을 가져옴 .map(user -> new UserResponse(user.getId(), user.getName(), user.getAge())) .collect(Collectors.toList()); } 자바 문법을 이용해 더 간단하게 변경 가능(자바 8버전을 이용한 stream)stream 으로 만들어서 mapping 후 유저리스트로 다시 만듦 .collect(Collectors.toList());⇒ 즉 유저 객체를 가져와서 객체 간의 변환하게 됨findAll() : 모든 데이터를 가져옴(select * from user;) 유저 업데이트 기능id를 이용해 User을 가져와 User가 있는지 없는지 확인하고User가 있다면 update 쿼리를 날려 데이터 수정(없으면 예외 던짐)UserServiceV2// 유저 업데이트 public void updateUser(UserUpdateRequest request){ // 원하는 sql : select * from where id = ?; // 반환값 : Optional => 매핑했던 user 객체 User user = userRepository.findById(request.getId()) .orElseThrow(IllegalArgumentException::new); // 유저가 없다면 예외, 유저가 있다면 결과값 들어옴 user.updateName(request.getName()); // 유저의 객체를 가져와 업데이트 // request.getName() -> 변경되어야 하는 api의 이름 userRepository.save(user); // 자동으로 user의 이름이 바뀌어있는걸 확인하고 바뀐걸 기준으로 업데이트 쿼리가 날아감 } findById : id를 기준으로 조회 지금까지 사용한 기능save : 주어지는 객체를 저장하거나 업데이트 시켜줌findAll : 주어지는 객체가 매핑된 테이블의 모든데이터 가져옴findById : id를 기준으로 특정한 1개의 데이터 가져옴어떻게 Sql을 작성하지 않아도 동작하는걸까?!JPA가 자동으로 처리하는겅가? 반은 맞고 반은 틀림⇒ Spring Data JPA 가 하는 것임 ( Spring Data JPA ≠ JPA)Spring Data JPA : 복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리 유저 삭제 기능⇒ spring JPA로 바꾸기삭제는 이름 기준인데 이름 기준 조회는 없음💡 어떻게 select * from user where name = ? 을 어떻게 만들 수 있을까?⇒ UserRepository interface에 들어가서 유저 반환 함수 만들기User entity 객체에 있음UserRepositorypublic interface UserRepository extends JpaRepository { User findByname(String name); // -> select * from user where name = ?; } 반환 타입은 User, 유저가 없다면 null 반환함수 이름을 작성하면, 알아서 sql 조회되는 방식임 ⇒ 함수 이름을 기본 함수처럼 만들어야 함find 라고 작성하면, 1개의 데이터만 조회By 뒤에 붙는 필드 이름으로 SELECT 쿼리의 where 문이 작성됨UserServiceV2// 유저 삭제 public void deleteUser(String name){ User user = userRepository.findByname(name); if (user == null) { throw new IllegalArgumentException("User not found"); } userRepository.delete(user); // 무조건 유저가 존재함을 의미(없으면 예외처리가 되니깐) } delete : 주어지는 데이터를 db에서 제거함 다양한 Spring Data JPA 쿼리에는 무엇이 있을까? By 앞에 들어갈 수 있는 기능find : 1건을 가져옴. 반환 타입은 객체가 될 수도 있고, Optional이 될 수도 있음findAll : 쿼리의 결과물이 N개인 경우 사용. List 반환exist : 쿼리 결과가 존재하는지 확인. 반환 타입은 boolean (존재하면 true, 존재 X false)count : sql의 결과 개수를 셈. 반환 타입은 long (ex. long countByAge) By 뒤에 들어갈 수 있는 기능 ( findByName )각 구절은 And 나 Or 로 조합할 수 있음List findAllByNameAndAge(string name, int age); => SELECT * FROM user WHERE name =? AND age = ?; GreaterThan : 초과 ( 필드명 뒤에)GreaterThanEqual : 이상LessThan : 미만LessThanEqual : 이하Between : 사이에 트랜잭션트랜잭션 : 쪼갤 수 없는 업무의 최소 단위 만약 쇼핑몰 사이트에서 물건을 주문하면주문 기록 저장포인트 저장결제 기록 저장public class OrderService { public void completePayment() { orderRepository.save(new Order(..)); pointRepository.save(new Point(..)); billingHistoryRepository.save(new BillingHistory(..)); } } billingHistoryRepository.save(new BillingHistory(..)); 에서 만약 에러가 난다면?⇒ 주문 정보 데이터가 있고 포인트 저장 데이터가 있는데 결제 기록에는 안 뜨게 된다pointRepository.save(new Point(..)); 에서 만약 에러가 난다면?⇒ 주문 기록은 있는데 포인트와 결제 기록이 없다모든 sql을 성공시키거나, 하나라도 실패하면 모두 실패시키자!⇒ 쪼갤 수 없고 한 몸이다 ⇒ 트랜잭션 트랜잭션 명령어start transaction; // 트랜잭션 시작 commit; // 정상 종료 rollback; // 실패 처리성공 처리시키면 보이고(commit) 실패 처리 시키면 안 보임(rollback)우리의 코드에 어떻게 적용할 수 있을까?public class OrderService { public void completePayment() { orderRepository.save(new Order(..)); pointRepository.save(new Point(..)); billingHistoryRepository.save(new BillingHistory(..)); } } completePayment() 함수가 시작되기 전에 트랜잭션을 시작하고모두 성공하면 commit 하나라도 실패하면 rollback을 시키자우리 프로젝트에서 트랜잭션을 사용하려면@Transactional 사용해 적용시키면 된다. UserServiceV2@Service public class UserServiceV2 { private final UserRepository userRepository; public UserServiceV2(UserRepository userRepository) { this.userRepository = userRepository; } // 유저 생성 @Transactional public void saveUser(UserCreateRequest request){ userRepository.save(new User(request.getName(), request.getAge())); } // 유저 조회 @Transactional public List getUsers(){ return userRepository.findAll().stream() .map(UserResponse::new) .collect(Collectors.toList()); } // 유저 업데이트 @Transactional public void updateUser(UserUpdateRequest request){ // 원하는 sql : select * from where id = ?; // 반환값 : Optional User user = userRepository.findById(request.getId()) .orElseThrow(IllegalArgumentException::new); // 유저가 없다면 예외, 유저가 있다면 결과값 들어오고 user.updateName(request.getName()); // 들어온 이름 userRepository.save(user); // 자동으로 user의 이름이 바뀌어있는걸 확인하고 바뀐걸 기준으로 업데이트 쿼리가 날아감 } // 유저 삭제 @Transactional public void deleteUser(String name){ User user = userRepository.findByname(name).orElseThrow(IllegalArgumentException::new); userRepository.delete(user); // 무조건 유저가 존재함을 의미 } } SELECT 쿼리만 사용한다면, readOnly 옵션을 쓸 수 있음트랜잭션을 사용했을 때 데이터 변경을 할 수 없음 ⇒ 보통 조회에 사용 영속성 컨텍스트 : 테이블과 매핑된 Entity 객체를 관리/보관하는 역할User.java@Entity // 엔티티 public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id = null; @Column(nullable = false, length = 20) // name(varchar) = 20 private String name; private Integer age; // id, name, age => 테이블관 매핑된 객체 스프링에서는 트랜잭션을 사용하면 영속성 컨텍스트가 생겨나고, 트랜잭션이 종료되면 영속성 컨텍스트가 종료됨. ⇒ 즉 트랜잭션과 함께 생겨나고 트랜잭션과 함께 종료됨 영속성 컨텍스트의 특수 능력 4가지변경 감지(Dirty Check) : 영속성 컨텍스트 안에서 불러와진 Entity는 명시적으로 save 하지 않더라도, 변경을 감지해 자동으로 저장됨쓰기 지연DB의 insert / update / delete sql을 바로 날리는 것이 아니라 트랜잭션이 commit될 때 모아서 한 번에 날림 쓰기 지연이 없다면? ⇒ A, B, C를 각자 저장 → spring과 db 사이의 통신이 3번 일어남(시간이 오래 걸림)쓰기 지연이 있다면? ⇒ 3번 통신했지만 한 번에 저장하기(시간이 빠름)1차 캐싱영속성 컨텍스트가 없다면 3번 통신이 일어남첫번째 코드가 실행되면 조회 (영속성 컨텍스트가 id가 1인 유저 기억) → 두번째 코드가 실행되면 id가 1인 유저를 이미 알고 있어서 가지고 있는 정보를 내보냄과제 6. Layered Architecturehttps://velog.io/@dmsqls19/인프런-워밍업-클럽-1기-BE-과제6.-기능-분리 회고이 이후 섹션부터는 지금 공부 중에 있다. 아무래도 내 다짐과는 다르게 너무 공부를 덜 한 느낌이라 시간이 된다면 완주한 후에 발자국을 남겨보도록 하겠다. 사실 강의 정리는 계속 강의를 들으면서 따로 정리하고 있기 때문에 나중에 다 완강하고 한 번 더 들으면서 제대로 공부해 볼 생각이다. 이번주는 과제도 한 개 밖에 제출하지 못 했다. 여러모로 아쉬운 한 주다ㅠㅜ https://quartz-mastodon-ac1.notion.site/6ae20b419ca9400c94b4df9ab8f2f3da?pvs=74
백엔드
![[인프런 워밍업 클럽 스터디]BE 1기 두번째 발자국](https://cdn.inflearn.com/public/files/blogs/04a0febd-35e5-4877-ad7c-1d6f5850f2e1/fd.png?w=260)
2024. 05. 12.
0
[인프런 워밍업 클럽 스터디]BE 1기 두번째 발자국
저번주에 호기롭게 다짐했던 이번주에는 공부를 미리 다해보자!라고 했는데오히려 저번주보다 공부를 덜 했다...분명 할 시간이 많을거라 생각했는데 이것저것 해보던 취준과 여행의 여파로 너무 피곤하기만 해서 뭘 제대로 해보지도 못하고 한 주가 지나갔다.열심히 해보려던 과제도 결국 두 개 중 하나만 제출하고 너무 허무한 한 주이다.그래서 그런지 더욱 머리에 내용이 안 남지만,, 낼부터는 진짜 열심히 해야겠다고 다시 한 번 다짐한다!! 이번주에는 나름의 복습으로 저번주에 공부하면서 정리했던 내용들을 다시 읽어보았다.사실 자바도 익숙하지 않아서 스프링은 더 안 낯선 언어인데 그래도 한 번 쓰면서 공부해봤다고 조금 눈에 익은 것 같다.섹션3 밖에 다 하지 못 했지만 다음주에는 얼른 진도에 맞춰 끝내놔야겠다. Section3역할의 분리와 스프링 컨테이너라는 제목이다.역할의 분리가 얼마나 중요할까?에 대해서 생각하면서 코드를 짜본적은 없던 것 같다. 아무래도 급하게 프로젝트만 하니 아 그냥 분리하는게 좋구나 해서 분리했던 기억이 난다. Layered Architecture3단 분리를 해야하는 이유?!💡 Controller에서 모든 기능을 구현하면 왜 안 될까?=> 함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다고 설명해주셨다. 클래스는 작아야 하며 하나의 책임만을 가져야 한다.예를 들어, 만약 controller 함수 1개가 3000줄이 넘으면?그 함수를 동시에 여러 명이 수정할 수 없음그 함수를 읽고, 이해하는 것이 너무 어려움그 함수의 어느 부분을 수정하더라도 함수 전체에 영향을 미칠 수 있기 때문에 함부로 건들 수 없게 됨너무 큰 기능이기 때문에 테스트도 힘듦종합적으로 유지보수성이 매우 떨어짐결국 이런 이유로 Controller에 모든 기능을 넣기 보다는 Service와 Repository에 나누는 게 좋다!!여태 작성했던 코드는API의 진입 지점으로써 HTTP Body를 객체로 반환현재 유저가 있는지 없는지 확인하고 예외 처리함SQL을 사용해 실제 Database와의 통신을 담당를 Controller에서 모두 하고 있었는데 1번은 Controller, 2번은 Service, 3번은 Repoitory로 나누는 작업을 한다. 3가지 역할을 나누는 것을 Layered Architecture 라고 하는데Controller ← Service ← Repository (DTO는 계층 간의 정보 전달 역할) 로 나눠진다. 이 때 기능만 나눠서는 안 된다. 우리는 JdbcTemplate 를 파라미터로 계속 받고 있어 오류가 생긴다.해결 방법은 UserRepository 도 Usercontroller 처럼 JdbcTemplate 를 변수로 받으면 된다. 그럼 또 다음과 같은 의문점이 생긴다💡Controller에 있는 JdbcTemplate 는 어디서 온 걸까? → Repository에서 바로 JdbcTemplate를 가져올 수는 없을까?답은 @RestController이다.@RestController어노테이션을 사용하면 UserController 클래스를 API의 진입 지점으로 만들 뿐 아니라 UserController 클래스를 스프링 빈으로 등록시키는 역할을 해준다. 스프링빈이란?서버가 시작되면, 스프링 서버 내부에 거대한 컨테이너를 만들고, 컨테이너 안에는 클래스가 들어가게 됨⇒ 이 때 다양한 정보도 함께 들어있고, 인스턴스화도 이루어짐즉, 이때 스프링 컨테이너 안으로 들어간 클래스를 스프링 빈이라고 한다.JdbcTemplate도 이미 스프링 빈으로 등록되어 있음JdbcTemplate은 우리가 build.gradle에서 설정한 dependency(의존성)에서 등록해주고 있었다! 스프링 컨테이너는 필요한 클래스를 연결해준다서버가 시작되면 다음과 같은 일이 일어나는데스프링 컨테이너(클래스 저장소)가 시작기본적으로 많은 스프링 빈들이 등록됨(JdbcTemplate)우리가 설정해준 스프링 빈 등록(UserController)이때 필요한 의존성이 자동으로 설정됨💡 그렇다면 왜 UserRepository는 JdbcTemplate을 가져오지 못할까?⇒ JdbcTemplate 을 바로 가져오려면 스프링 빈이어야 하는데 UserRepository는 스프링 빈이 아니다⇒ UserRepository를 스프링 빈으로 등록해보자!!여기서 Repostitory에는 @Repostitory Service에는 @Service 를 각각 등록해주면 스프링 빈으로 등록된 것이다. 💡 좋아진 것 같긴 한데 왜 스프링 컨테이너를 사용하지? 그냥 new 연산자 쓰면 되는거 아닝가?? 라는 의문이 들 것이다.책을 저장하는 api를 만든다고 가정해보자.그럼 Controller, Service, Repository 이렇게 구성하고 만들 것이다.이 때 db를 메모리에만 저장하는 코드로 구성했다가, MySql과 같은 db에 저장한다고 하면repository가 수정될 때마다 새로 new BookMySqlRepository(); 이런 식으로 계속 추가해야 한다.자동으로 연결해주기 위해 스프링 컨테이너를 활용한다! 스프링 컨테이너란 컨테이너가 BookService를 대신 인스턴스화 하고 그 때 알아서 BookRepository를 결정해주는 건데 BookService와 BookRepository가 모두 스프링 빈이라면 스프링 컨테이너는 BookService를 알아서 인스턴스화 하고BookRepository를 결정해줄 것이다. BookRepositorypackage com.group.libraryapp.repository.book; import org.springframework.stereotype.Repository; @Repository public class BookMySqlRepository implements BookRepository{ @Override public void saveBook() { } } BookControllerpublic class BookController { // 2. BookService 연결 => 스프링 빈이 아닌 경우 private final BookService bookService; // instance화 할 필요 X public BookController(BookService bookService) { this.bookService = bookService; } // 생성자 추가(constructor)이렇게 하면 알아서 어떤 레포지토리를 불러올지 결정한다.이때 레포지토리가 너무 많다면 @Primary 를 사용해 어떤 레포지토리를 우선순위에 둘지 레포지토리에 직접 설정해준다. 빈을 사용하는 방법@Configuration와 @Bean 이 있는데 둘은 항상 같이 사용해야 한다.@Configurationclass에 붙이는 어노테이션@Bean 을 사용할 때 함께 사용해 주어야 함@Beanmethod에 붙이는 어노테이션메소드에 반환되는 개체를 스프링 빈에 등록@Configuration 이라는 어노테이션은 보통 config 라는 패키지에 만든다.@Component주어진 클래스를 컴포넌트로 간주컴포넌트로 간주된 클래스들은 스프링 서버가 뜰 때 자동으로 감지된다.@RestController, @Service, @Repository, @Configuration 어노테이션은 모두 @Component 어노테이션을 가지고 있음 스프링 빈을 주입 받는 방법생성자를 이용해 주입받는 방식 (가장 권장) setter를 통해 주입받는 방식필드에 직접 주입하는 방법권장 Xsetter를 통해 다른 인스턴스로 교체해 동작에 문제가 생길 수 있음필드에 바로 주입하게 되면 테스트가 어려움 과제5클린 코드에 대해 배우고 클린 코드 직접 작성하기https://velog.io/@dmsqls19/인프런-워밍업-클럽-1기-BE-과제5.-클린-코드Clean-Code 느낀 점일단 이번주에 공부를 너무 안 해서,,, 조금 회고록이 짧은 것에 대해 반성해야겠다.그리고 배우면서 느낀건 클린코드가 정말 중요하다는 걸 깨달았다.내가 쓴 코드에 대해 설명할 때 이건 왜 이렇게 구성했는지에 잘 파악하면 된다고 생각했는데 줄일 수 있는 건 최대한 줄이면서 간결하게 하는 것도 중요하다는 걸 느꼈다. 코드가 왜이렇게 복잡하지? 했던 것도 다 줄일 수 있는 것들이었다.배운 것보다 배울 게 더 많다 라는 생각과 함께 걱정은 되지만 새로운 걸 배우는 건 늘 재밌기 때문에 다음주도 기대가 된다.
백엔드
![[인프런 워밍업 클럽 스터디] 1기 첫번째 발자국](https://cdn.inflearn.com/public/files/blogs/61352b46-d966-45c2-84ec-32aa35ef8dc1/인프런워밍업클럽.png?w=260)
2024. 05. 03.
0
[인프런 워밍업 클럽 스터디] 1기 첫번째 발자국
발자국 남기기벌써 일주일이나 지나고 있다니 시간이 진짜 빠르다. 아무래도 신입을 많이 뽑지 않는 지금 시점에서 할 수 있는 건 공부뿐이라고 생각해서 미루고 미루다 자바 공부를 시작하며 스프링 공부를 해야겠다고 맘 먹었다. 근데 또 혼자하면 늘어지는 스타일이라 차라리 같이 공부하고 돈도 내고 해야 열심히 할 것 같아 스터디를 듣게 되었다..!! 근데 생각보다 내 일정이 빡빡해지는 바람에 1주차인 지금은 시간에 쫓기듯 공부하고 있지만 담주부터는 여유롭게 들을 수 있을 것 같다. 그럼 이제 1주간의 회고를 시작해보겠다!! Day0강의를 듣기에 앞서 OT를 온라인으로 진행했다. 앞으로 어떻게 진행되는지의 전반적인 부분을 말씀해주셨다.그리고 자바에 대한 짧은 특강을 해주셨다. 자바는 인터프리터? 컴파일 언어?프로그래밍 언어는 컴퓨터가 이해할 수 있는 언어로 번역해야한다 번역의 종류→ 통짜번역 ⇒ 컴파일러→ 그때그때 번역 ⇒ 인터프리터자바는 하이브리드 언어임(둘 다 가능) .Java → (compile) → .class → JVM컴파일도 하면서 한줄 한줄 읽음 시작부터 유용한 정보를 알려주셔서 넘 좋았다. tmi지만 최근에 정처기 실기를 공부해서 아는 내용이라 공부를 안 하고 있는 건 아니구나 라는 안심을 조금 했다😅 Section0강의를 시작하기 전의 섹션 0 에서는 강의 시작 전 준비와 수업 자료에 대한 내용이었다.대부분의 내용은 이미 알고 있던 거고 다 다운받아져 있던 거라 설명만 조금 들었다.지금 내 노트북은 맥북 m2인데 사실 그냥 homebrew로 다운 받으면 버전이 안 맞거나 잘못 받아서 경로가 이상해지는 현상이 많이 발생한다.이전에 MySQL을 설치하면서 많은 충돌이 있어서 나중에 잊지 않으려고 블로그와 노션에 열심히 정리해두었다.https://velog.io/@dmsqls19/ERROR-mac에서-MySQL-완전-삭제-후-재설치-오류Homebrew-사용했을-경우나중에 같은 오류가 있다면 이 글을 보고 있는 분도 잘 해결했으면 좋겠다! Section1섹션 1부터는 본격적인 강의 시작이다.자바를 공부하기 전에 알아두면 좋은 강의 2개를 올려주셨는데 정말 유익한 내용이다.첫번째 강의에서는 Java라는 언어를 컴퓨터가 알게 되기까지의 과정이 나오는데 컴파일을 통해 사람의 언어를 컴퓨터가 인식하게 된다고 한다. 자바는 다른 언어와 다르게 컴파일러 하나로 모든 운영체제에 사용할 수 있다.JDK > JRE > JVM 라서 JDK를 설치하면 JRE와 JVM도 함께 설치된다.JDK의 버전과 종류는 다양한데 LTS라는 안정화된 버전을 사용하는 것이 좋다.두번째 강의에서는 빌드와 실행에 대해 배우는데 빌드란 소스 코드 파일을 컴퓨터에서 실행할 수 있는 독립 SW 가공물로 변환시키는 과정이다. 테스트 코드도 빌드 과정의 일부인데 테스트 코드를 작성해서 개발 속도 및 안정성의 품질을 높여주는 것이 좋다. 그 다음 오픈 소스와 우리가 만든 코드를 합치는 과정을 패키징이라 하는데 패키징을 하면 빌드 과정의 끝이다. 실행(Run)을 해서 내가 작성한 코드를 작동시킬 수 있는데 Artifact가 나올 수도 있고 나오지 않을 수도 있다는 점에서 빌드와 차이점이 있다. 빌드는 수동으로 하게 되면 실수가 많이 나올 수 있으므로 빌드 툴을 이용하는 것이 좋은데 요즘 가장 많이 쓰이는 빌드 툴은 maven과 gradle이다.이제 본격적으로 강의를 시작하는데 처음에는 스프링 프로젝트를 시작하는 방법에 대해 배운다. 그 다음 @SpringBootApplication 에 대해 배우면서 어노테이션이 무엇이고 서버란 무엇인지에 대해 배운다.첫번째 과제가 바로 어노테이션에 관한 과제였다. 스스로 찾아보면서 공부를 하니 이해가 더 잘 되는 것 같기도 하면서 아리송하기도 하다. 📄과제1. 어노테이션 그 후 네트워크와 HTTP, API에 대한 것을 배우는데 백엔드를 공부하는 사람에게 필요한 내용을 배워서 좋은 강의라고 느끼는 부분이았다.api에 대해 배운 후 get과 post를 직접 해보는데 처음에는 더하기, 곱하기를 해보며 postman도 써보고 코드도 직접 작성해봤다. 그 다음에 유저 정보 조회를 하는 get api와 유저 정보를 저장하는 post api에 대해 배웠다. 미리 get과 post를 해보고 하니 더욱 쉽게 느껴졌다. 두번째 과제는 get api와 post api를 직접 연습하는 과제였는데 자바에 좀 덜 익숙해서 그런지 좀 어려운 과제였다. 그래도 두 번 보니 처음 과제를 마주했을 때보단 쉬웠다.📄과제2. GET API, POST API Section2섹션2에서는 서버와 데이터베이스를 연결하는 과정이다. 데이터베이스는 MySQL을 사용했다. 데이터베이스가 서버에 필요한 이유는 메모리에서만 유지되는 유저 정보를 서버단에 올리기 위해서 필요하다. 강사님이 서버에 올리는 두 가지 방법을 알려주셨는데 하나는 인텔리제이 유료 버전으로 인텔리제이에서 하는 방법과 터미널에서 MySQL을 사용하는 방법이었다. 나는 인텔리제이에서 하는게 더 편한 것 같아 첫번째 방법을 사용했다.데이터베이스에 대해 공부하고 sql 문법에 대해 배운다. 나는 최근에 정처기 시험 때문에 이미 너무 많이 봐서 어렵게 느껴지진 않았다. 그 후 스프링과 데이터베이스를 연결하는 과정을 배우는데 코드 따라치는 건 어렵지 않은데 자바가 익숙한 건 아니라서 이해를 하는데 조금 오래 걸렸다. 그래도 오래 보다보면 또 이해가 되기 때문에 조금 더 많은 시간을 들여 공부를 해야겠다고 생각했다.연결 후에는 유저 업데이트와 삭제를 해보면서 정말 db에 유저 정보가 들어가는지 확인했다. 그 다음 유저 정보가 없을 경우에 업데이트, 삭제가 되는 예외처리를 해주었다.그리고 과제로는 sql을 연결해보며 나온 람다식에 대해 조사하는 과제였다. 찾아보면서 이해 못한 부분을 조금 더 이해하게 되었다.📄과제3. 익명 클래스와 암다식 5일차에는 중간점검이 한 번 있었는데 질문하는 것을 답변해주는 시간이었다.나도 신입 개발자로서 궁금했던 점들을 다른 분들이 많이 질문해주셔서 답변을 들으며 엄청 유익해서 뭔가 이런 시간이 조금 더 많으면 좋겠다는 생각이 들었다.이번주는 시간이 조금 빠듯해서 진도표보다 조금 덜 공부했다. 다음주는 시간이 많아서 아마 더 할 수 있을 것 같다. 한 주 동안 공부해보면서 아직 자바 공부가 많이 부족하다는 걸 깨달았다. 그래서 다음주는 자바 공부를 하면서 강의를 들을 예정이다. 공부하면서 회고도 하고 과제도 하니 진짜 같이 공부하는 기분이 들어 더 열심히 해야겠다고 다짐했다!! 📚공부했던 내용 정리 노션 https://quartz-mastodon-ac1.notion.site/6ae20b419ca9400c94b4df9ab8f2f3da?pvs=4
백엔드
・
인프런워밍업클럽1기BE




