Vue springboot
인스턴스화 해서
IOC 하는데 RestController 이렇게 붙여놓으면 스프링 구동하면서 이 헬로우 컨트롤러 인스턴스 만든다음에 스프링내부로 만든다 그리고 한번만 딱 호출한다 인스턴스 여러번 호출 한데 한번만 실행하는 걸 싱글턴 패턴으로 한번만 실행
필요할 떄 주입하는게 DI 싱글턴패턴으로 만들어서 자기 컨테이너에 갖고있다ㅣ
그냥 컨트롤러는 페이지를 리턴하고
RestController는 데이터를 리턴
모바일 등장하면서 리소스를 등장하고 xml,json을 리턴해야 되서 restcontr
Request메서드는 모든 매핑이 다 호출이 가능하다.
get
에러는 톰캣 서버가 내고 읽어서 내는거라 post 허용 안해서 내는 거.(http 프로토콜)
RequestParam 은 url 쿼리스트링 올떄 받는거 get매핑 으로 네임으로 주면 값을 받음.
스프링은 쿼리 파라미터 받는 규칙이 RequestParam그리고 뒤에 ? 로 key=value이렇게 보낸다. 프로토콜이다.
스프링에서 받는게 스프링 규칙이다
request
url 에 파라미터 받을 때는 name에 PathVariable에 name으로 url파라미터 받게 됨.
얘들을 스프링에서 구현하는 건 PathVariable로 받는다는 게 중요하다.
쿼리 파라미터와 url파라미터로 설.
문법적으로만 똑같음.
개발 할 때 프로토콜 상황은 차이가 없음. 경우 따라서
get은 뒤에 url에 쿼리파라미터 내보내고 post는 쿼리 파라미터 받는 건 상관이 없다. get은 프로토콜 상에 get은 body를 보낼 수 없다. post는 body가 있음. get은 바디가 없어서
content타입이 x-www-form-urlencoded로 날아옴.
http 프로토콜이다 디비 관련 마이바티스 JPA 이 둘을 알아야 rest만드는 기반이 됨.
위가 request, 밑은 ResponseBody 헤더와 body로 이뤄짐.
한칸이 띄워진 이유는 헤더와 바디로 이뤄짐.
리퀘스트 해서 x-www-url-urlencoded 이게 형식인데 쿼리파라미터와 비슷
얘는 리퀘스트, 리스폰 둘다 존재 가능. http 프로토콜을 이해를 해야됨.
아까처럼 쿼리 파라미터로 받을 수 있지만 x-www-url방식으로 받기 가능.
쿼리 파라미터 ulr 로 바디도 같이 받을 수 있다.
롬복 밑에 두개 속성을 게터 세터 자동으로 만들고 둘중 하나만 만들고 싶으면 @Getter, @Setter
파라미터가 없
롬복 안 썼으면 메모리 주소 나왔을 ㄱ너데 롬복 쓰면 toString이 지원 되어 있어서 이걸 오버라이드 해서 찍는데 이걸 tostring 구현해서 이걸 찍으면 메모리 주소 찍게끔
body 형태가 json이라는 거
리퀘스트, 리스폰 다 있을 수 있다. 바디에 대한 컨텐츠를 줌. 스프링에서는 json으로 리턴한다고 json으로 만들어서 리턴하는게 아니라 인스턴스 리턴하면 변환이 자동으로 됨.
jacksonMapper라는게 포함되어 있어서 객체 인스턴스
@RequestBody는 파람과 다르네?
Body에 있는걸 모아서 객체로 변환해라
RequestBody에 있는 객체를 가져와서 VO로 변환해라
아까는 객체를 리턴하니까 자동으로 json으로 변경했는데 리퀘스트에 json을 던져주면 그 바디를 꺼내서 VO로 넣어주겠다.
둘다 잭슨 매퍼가 해준다. 양쪽으로 해주는게 전부 잭슨매퍼가 해준다.
Rest는 표준이 아니다. get도 데이터 생성이 가능하다.
ORM이 없으면 쿼리문을 직접 만들어줘야한다.
도커 및 저기에 계정이랑 마리아디비 만드는 과정이고
-p 3306:3306 왼쪽은 로컬 포트이고 오른쪽은 docker에서 실행된 db 포트이다.
왼쪽은 도커디비랑 연결할 포트랑 3306으로 하겠다라는건데 설치 되어있으면 왼쪽을 3306 못쓰니까 왼쪽을 3307을 바꾸면 로컬의 3306을 3307로 바꾸니까 컨테이너 쓸수 있다는 뜻.
백엔드 팀으로 구분
피그마가 많이 쓰는 추세 화면 보고 백엔드 개발자가 api 설계해야됨.
UI가 나오면 erd를 설계해야됨(erd는 여러개의 테이블 사이의 관계)
테이블과 테이블 사이 관계 그림
entiti relationship diagram
웹개발 필수산출물
- erd
- api
- ui
가 3가지의 필수품.
이 산출물이 있어야 개발 가능. 진행하면 뭘할건지 정하고 UI 만들어야. 백엔드 개발자가 해야될 제일 중요한 게 DB 설계. ERD를 설계하는게 제일 중요하다.
users 사용자, 사용자가 favorites 으로 이 유저라는 테이블과 테이블 보면 유저쪽에 짝대기가 하나 있고 테이블 보면 삼각형 있는데 유저와 테이블 사이 관계 정의 1:many 정의. 이렇게 관계 설정하는게 ERD 다이어그램
rdb 실제 비즈니스 구현할 떄 rdb 쓰는 이유가 테이블 사이 관계 맺어놓으면 쿼리라는거 맺기 쉽기 떄문에 맺어둠.
1:1 관계 등 테이블 사이 관계 설정하는 표기법이 여러개 있음.
짝대기가 있으면 하나가 있다, 삼각형이면 많다.
유저와 테이블 관계는 1:N
게시판 하나에 여러댓글이 달린다 = 1:N
이런 릴레이션 정하는게 중요
사용자가 있으면 사용자와 게시판도 1:N(한명이 게시판 여러개 쓰니까)) board와 comment 사이에 foreign key를 달아줘야 하겠다라는건데
board와 comment가 foregin 키로 달려서 실행
화살표는 표준 erd 표기법은 아님.
표준 표기법으로 그리면 아까처럼 삼각형과 작대기가 있어야 한다.
erd를 그릴수 있는 툴이 많지는 않음.
표준 산출물로 erd로 그릴수 있는게 erwin 이런 유로툴이라던가.
erdcloud 를 쓰거나 이래야된다.
게시판에 들어갈 내용을 만듥 컬럼 만들고 댓글도 화면 보고 제목,ㅡ content 내용 이러넉 만들고 1:다 관계니까 foregin key를 만든거.
restApi 개발할 때 디비 설계가 70~80프로.
api 만드는 건 더 쉬울 수 도 있다.
설계 한다는 게 생각이 들어가서 화면을 그리면 화면에 따라 어떻게 그리고 어떤 관계를 맺어야 되는지 설계만 해놓으면 나머지는 메뉴얼대로 그리면 된다.
설계하는 게 개인마다 사고나 배움의 지식에 따라 normalized(정규화)를 할지 그리고 어떻게 관계를 맺을지, 어떤칼럼을 primary 키로 할지 이런 건 디비 관련.
ERD가 설계가 되었다는 가정하에 화면에서
데이터가 있어야 쿼리 날리니까 게시판 생성하는 api 만들어야.
여기 저장 누르면
제목, 내용 누르면 서버로 보내주면 나중에 로그인 하면 사용자 아이디랑 이런거 서버에 보내면 저장하는 RESTAPI 를 만들어야됨.
게시판 생성하는 api
잭슨매퍼가 제이슨으로 만들어줌 반대로 제이슨을 객체로 만드는거도 잭슨매퍼가 함.
만일 어떤 값이 널인 경우 제이슨으로 만들지 말라고 하는게 JsonInclude
만약 null 이라면 json으로 만들지 말라는 뜻.
아이디를 널로 줬는데 0으로 리턴되는 경우가
만약 int로 되면 원하는 값이 들어갈 수 있다. 제이슨을 만들 때 그걸 내가 클라이언트에 전달하지 않고 싶으면 널이 되서 포함을 안시킴.
여기가 BoardVO를 만든건 매핑이 된다.
xml로 작성하면 작성하는 양이 많아지면 자바 코드에서 이동할 떄 코드 찾기가 힘들다.
자바 코드로 짜놓게 되면 코드로 찾기가 쉬워진다. 자바코드를 아직 잘 모를 수 있다. 대부분 사람들도 xml로만 할 줄 알지 자바코드로는 xml로도 100프로 변환이 가능하다.
@Mapper는 @Service, @Controller 해서 인스턴스화 해서 컨테이너에 갖고 있다.
8번쨰 줄은 인터페이스를 인스턴스화 하는건데 이걸 인스턴스화를 사실 못하는데(new를 못하는데) 인터페이스 를 구현하는 클래스를 만들고 그걸 인터페이스를 인터페이스화 해서 스프링 쪽에 가지고 있는다라고 생각하면 된다.
싱글턴 패턴으로 인스턴스화 해서 컨테이너에 가지고 있다.
스프링은 DI,IOC, 디펜던시 ,
이 4가지만 알면된다.
그중 가장 중요한게 DI고 80프로 이해가능.
JPA를 하면 개념이 많이 달라짐. 쿼리문 하나도 모르고 자바 객체만으로 하는게 가능함. JPA하게 될 일이 있다면 2번쨰 노드 js 방식이 jpa 방식이 가능은함
jpa쿼리는 쿼리를 짜는게 아니라 마이바티스의 단점 마리아 디비 쓰고 있는데 오라클로 바꾸고 싶으면 오라클이 insert부분을 다시 개발해야된다.
만약 우리는 마리아 디비가 아니라 오라클을 쓰고 있으면 고객사에 따라 쿼리 100개를 오라클용으로 다 바꿔야하는데 jpa는 자바객체를 다루기 때문에 boardVO라는 엔티티 클래스를 다루고 엔티티에 따라 insert에 따라 객체에 따라 테이블에 대한 인서트 쿼리문을 날려주기 떄문에 오라클이 되든 마리아디비든 상관 없이 객체만 들어옴.
앞서가는 기업은 전부 JPA 이런거 쓰고 있음. 대신 대기업은 MYSQL을 많이 쓰고 있음. 벤쳐쪽이라던가 약간 기술 앞서가는 곳 가면 JPA 쓸 것.
인터페이스 만들고 클래스 만들고 이런건 정해진 규칙은 아니고 인터페이스 만드는 가장 큰 목적은 공통화 하는거.
하나밖에 없는 데도 불구 하고 꼭 인터페이스 만들고 이럴 필요가 없다. 배웠으면 자유롭게 쓸 수 있는 게 중요. 리팩토링이란건 덩치 커질수록 날 마다 하는 거.
Board 컨트롤러도 스프링 구동되면
client로 부터 들어온 api를 받아야되는데 어노테이션이 re
api로 들어오는 모든 요청은 BoardMapper가 들어간다.
BoardMapper가 컨테이 들고 있는데 스프링 컨테이너에 인스턴스가 있는데 이 Autowired를 붙이게 되면 컨테이너에 갖고 있는 걸 스프링에 주입을 하게 됨.
문제는 서로서로 어긋날 수 있음.
User라는 클래스가 있고 A라는 클래스가 있는데 유저라는 클래스에서 A를 인스턴스화 하고 a의 함수 호출하면 A라는 클래스는 유저가 직접 A를 제어하게 됨.
근데 문제점이 강한 결합성이 있어서(dependency) 이렇게 하진 않고 class A 에 COntroller를 붙이면 스프링이 구동되면 스프링이 IOC에 등록하고 이런 인스턴스가 전부 등록이 된 상태가 됨.
User라는 클래스가 여기에 private에 Autowired를 붙이게 되면 주입을 하게 됨.
a라는 클래스를 생성하고 제어하는 주체가
유저가 A라는 클래스를 생성하고 제어하는 주체가 Spring 컨테이너로 바뀜.
User가 이렇게 하면 생성하는 주체가 스프링이 되어서 이제 제어가 역전이 됨.
유저가 제어하던걸 스프링이 직접 제어한다.이걸 스프링 ioc 컨테이너라 부른다.
주입을 하는걸 DI라 하고
제일 중요한게 DI, AOP 인데 실제 쓰는 건 DI 가 90프로
거의 대부분이 스프링이 90프로 씀.
문제는 private A를 했고 인스턴스를 생성하는 순서는 스프링이
인스턴스화 하다보니까 Autowird붙었고 주입을 해야되니까 인스턴스화 안된 상황에서 Autowired를 만나면 controller를 먼저 만남.
알파벳이 빨라서 Autowired를 만나면 인스턴스화 하기위해 컨트롤러 먼저 실행.
유저가 A필요해서 A 먼저 실행하는데 A갔는데 유저가 필요하네?
@Autowired는 그래도 실행됨.
상호 디펜던시 걸려있으면 에러 안뱉고 런타임 되었을 떄 에러나기 때문에 이렇게 하지말고 생성자로 주입하도록 권장.(이걸 명확하게 상호 디펜던시 걸렸다고 에러남.)
대신 생성자 주입을 했을떄 private 해서 또 주입 받으면 번거로움.
롬복에서 @Autowired + alter RestController
final이 붙은 생성자를 @RequiredArgsConstructor 쓰면 생성자 붙여줌.
생성자는 많아지면 많아질수록 수정해야되는데 번거로우니까 롬복에서 속성에다가 final을 붙인 애에 대한 생성자를 자동으로
보드매퍼랑 인스턴스는 주입이 됐으니까 쓸 수 있는거고 20번쨰 보면 리퀘스트에있는 바디를 다져와서 주입해라 잭슨매퍼가 주입해준다.
생성했을때 클라이언트 쪽에서 제목과 내용 날려줄텐데 보드가 생성이 되면 그럴 경우엔 쫌 다르게 해야.
게시판 생성하고 게시판 생성하는걸 추가적으로 안하고 화면에 붙이고 싶으 면
swagger는 프론트가 달라하면 전달해주면 되고 서버개발자가 개발하면 포스트맨이 더 낳다.
버전 2.4.4
물논 이거를 난중에 그 수정하는 법도 있지만 그 unitTest로 만들어서 돌려도 되긴 함. api는 컨트롤러에서 api받았기 떄문에 api붙이
프라이머리 키 던져달라 하면 그거도 또 생각하면 됨
목록보기 상세보기 ㄱ
목록보기, 상세보기 같은 경우 이렇게 하게 되면 모든 내용을 다 가져와서 페이징이 필요한데 나중에 jpa 하게되면 좀 달라질 것.
상세보기니까 이 파라미터를 int로 던져주고 Url 파라미터 부분을 id 한 다음에 request Param이 아니라 Path Variable 로 보냈고
널까지 들어갔으면 그 부분은 포함 안됨.
목록 보기 페이지네이션은 로직.
페이지네이션에서 클라이언트 쪽 부분 보면 현재페이지가 몇페이지인지 한 페이지 몇개이닞 전체 갯수. 이게 있어야 페이지네이션 가능.
현재 페이지가 1이고 페이지 사이즈가 10개, 전체 게시판 개수가 155개가 있다
그럼 클라이언트가 페이지 목록바가 있어야 되고 몇 페이지인지 알아야 한다.
전체는 16페이지가 된다.
1,2…. 16
1=>2페이지 갈떄 서버에서 이 2가지 뿌려주면 되는데 클라이언트에선
프로토콜은 백엔드가 정하니까 알려주면 되긴 하지만 프론트가 알아야 어느정도 구현이 된다.
3가지 가능한걸 알고 있어야 목록 조회했을 때 프런트가 페이징 한다.
개발자가 어떻게 개발하느냐에 따라 다름.
세분화 하는게 확장성이 좋다. 어딘가에서 쓸 수 있다.
이런게 클래스 설계 원칙
SOLID 클래스 원칙
하나의 클래스엔 하나의 책임을 가지라. 이 원칙에 의해 게시판 전체 카운트를 하는 api 따로 만들고 조회하는 클래스 따로 만들고 이런식.
프론트엔드 역량이 있으면 api를 잘게 쪼개서 하면 확장성 있게 할수있다.
API를 잘게 쪼개면 쪼갤수록 확장성이 좋다. 그걸 합치면 해야되니까 A,B,C라는 API가 있으면 이걸 다 한꺼번에 만들어놨다고 하면
이 프런트 쪽에선 페이지 넘버와 사이즈 넘어온걸 쿼리파라미터로 본다. 얘를 쿼리파라미터로 두가지를 다 받아야하니까 RequestParam으로 다 받아야 한다.
페이지 넘버는 늘릴수 있으니까 Integer로 넣고 널일수 있으니까 Nullable로 받았다.
MariaDb는 Limit라는 특수 문장 사용도 가능
Limit가 없으면 0부터 가져옴.
페이지 사이즈가 1이라 하면 10개 가져와야
만약 널이면 findboard에서 if문을 타고
Wrapper 클래스 써야만 널이 아닐수 있음
int쓰면 0부터 올수 있으므로
프론트개발자가 한번에 달라하면 합치면 됨.
boardvo에 vo와 카운트 같이 담는거 만들어서 보내주면 됨.
제이슨 객체안에 카운트 속성과 보드라는 어레이리스트로 들어가서 이렇게 만들어서 조회 두번하고 카운트와 목록 넣은채로 리턴하면 잭슨매퍼가 변환해서 제이슨으로 들어감.