스프링 부트 1주차 정리

선장원·2022년 1월 9일
1

SpringBoot

목록 보기
5/18

1주차 (01/04~01/07)

지금 까지의 내용

수업내용 언어 IDE 프레임워크 설치
java java Eclipse - Open JDK 11
front html, css, javascript, jquery Visual Studio Code - -
Spring java STS(Spring Tool Suite) = Eclipse+spring3 Spring Framework 5.2.9 -
Spring Boot java Intellij IDEA Ultimate Spting Boot 2.5.3 -
DB mysql mysql workbench mysql server

와 table로 만드니 표가 만들어지긴하네?ㅋㅋㅋㅋㅋㅋㅋ

스프링 부트

MVC 기반
테스트 코드 작성 연습
DB

테스트 코드를 좀 줄임ㅠ

스프링 부트 구조

스프링 프레임 워크

스프링 부트

서비스 클래스에서 DTO를 Entity클래스로 변환 시켜서 Entity클래스를 Repository로 보내준다
Repository에서 jsp를 상속받아서 jsp에 있는 메서드를 사용해서 DB와 연동한다

스프링 프레임워크 vs 부트 차이점

기준 Spring Framework Spring Boot
화면 jsp thymeleaf
DB mybatis Spting Data JPA
dependency pom.xml gradle

스프링 프로젝트 만들기


name : 프로젝트 이름
type : Gradle
Group + Artifact :Package name

폴더 구조

  • 정적자원 static
    css, javascript, 이미지 파일

  • template
    화면(jsp, html등등)

REST API

REST(Representational State Transfer) API(Application Programming Interface)

  • 주소요청만으로 어떤 작업을 하고 싶은지 알 수 있다
    • 회원가입, 회원조회, 목록 출력, 상세조회, 수정, 삭제
  • 사용하는 Http Request Method
    • get(R), post(C), put/patch(U), delete(D)
    • GetMapping, PostMapping, PutMapping, DeleteMapping
  • 기존 주소 vs REST API
기능 기존 방식 - REST API -
회원가입 페이지 요청 /member/save GET /member/save GET
회원가입 /member/save POST /member/save POST
로그인 페이지 요청 /member/login GET /member/login GET
로그인 /member/login POST /member/login POST
회원목록 조회 /member/findAll GET /member/ GET
상세목록 조회(2번 회원) /member/detail?m_number=2 GET /member/2 GET
삭제(2번 회원) /member/delete?m_number=2 GET /member/2
/member/delete/2
delete
GET
수정화면 요청(2번 회원) /member/update?m_number=2 GET /member/update/2 GET
수정 처리(2번 회원) /member/update POST /member/2 PUT

delete, put은 대부분 ajax를 사용한다

Thymeleaf

<html lang="en" xmlns:th="http://www.thymeleaf.org">

html 위에 언어 설정부분을 이걸로 교체하면 타임이프로 바뀐다

모델로 DTO받아오기

컨트롤러

html

실행화면

th:object="${모델로 받은 이름}"

th:field="${필드 이름}"

오류 가져오기

설정

  • @NotBlank를 DTO필드에 설정
  • save처리(POST)에 @Validated를 DTO앞에 설정
  • BindingResult를 설정
  • html에 p태그에 th:if, th:errors 설정

순서

  • @NotBlank가 빈칸을 확인하면 오류를 전송
  • @Validated가 오류를 받음
  • BindingResult가 오류를 저장
  • if(bindingResult.hasErrors())로 오류가 있으면 실행
  • html으로 다시 보내면서 오류도 같이 전송
  • th:if으로 오류가 있으면 실행

@NotBlank

그리들의 디펜던씨에
implementation 'org.springframework.boot:spring-boot-starter-validation'

@Validated, BindingResult

  • @Validated
    유효성 검증 기능

  • BindingResult
    오류를 담아서 보내주는 기능

BindingResult.reject()

글로벌 오류를 보내주는 신기한 친구?

컨트롤러

html

th:if, th:errors, th:errorclass

th:if="${#fields.hasErrors('필드이름')}" : 오류가 있으면 해당 태그 실행

th:errors="*{필드 이름}" : if와 같이 사용

th:errorclass="field-error" : 해당 태그의 클래스 생성 css적용

화면 출력하기

th:each가 반복문 출력용이고 ""안의 값은 리스트를 지정해준다
th:text가 내용을 출력하고 여기 말고 다른곳에서도 사용함
타임이프로 출력하려면 이걸 써야하는 듯

주소 요청

th:href="@{|/member/delete/${member.memberId}|}"로 타임이프 문법안에 이걸 해줘야지
타임이프가 문자와 가져오는 데이터를 구별해서 입력을 한다

컨트롤러

함수호출

th:onclick="detail([[${member.memberId}]])"로 데이터를 [[]] 로 묶어줘야한다
묶었을 때 끝에 괄호에서 오류가 나오는데 무시해도 되는 오류이다

ajax의 url에 번호 보내기

const 변수를 만들어서 "/member/"+(가져온 데이터)를 해서 ajax용 url을 만들자

기존 했던 ajax에서 data만 빠진 모습이다
data에서 사용했던 번호를 url으로 넘겼으니 data는 할 일이 없어서 해고 당했다 ㅠ

컨트롤러

Entity클래스

JPA를 사용하기 위해서 DTO를 Entity클래스로 변환해서 보내주어야 한다

DB에 create, insert 등등을 안하게 해준다

Entity를 사용하면 테이블 join이 쉬워진다

설정

@Entity : Entity클래스 설정

@Getter, @Setter : Getter, Setter설정

@Table(name="테이블 이름") : 테이블 이름

@Id : PK 지정

@GeneratedValue(strategy = GenerationType.IDENTITY) : auto_increment와 같은 기능

@Column : 길이 지정, 유니크지정

필드 값에 _(언더바)넣으면 안됨

DTO를 Entity클래스로

static 메서드 사용
팩토리 메서드
이유
entity클래스의 생성자를 노출하지 않도록 함
가독성 있는 이름을 줄 수 있음
생성자는 리턴을 줄 수 없지만 메서드는 리턴도 가능

Entity클래스를 DTO로

의존성 주입

(DI, Dependency Injection)

  • 스프링이 객체를 관리할 수 있도록
    • @Controller, @Service, @Repository등

필드 주입 방식

@Controller
public class Controller {
	@Autowired
	private Service ms;
}

public interface Service{}

@Service
public class ServiceImple implements Service{}

생성자 주입 방식

@Controller
public class Controller {
	private final Service ms;

	@Autowired
	public Controller(Service ms){
	this.ms = ms;
}
}

public interface Service{}

@Service
public class ServiceImple implements Service{}

롬복 적용

@Controller
@RequiredArgsConstuctor
public class Controller {
	private final Service ms;
}

public interface Service{}

@Service
public class ServiceImple implements Service{}

@RequiredArgsConstructor

final이 붙은 변수만 롬복을 사용하게 해줌

final을 붙임으로서 더 오타를 줄여준다

application.yml

톰캣

mysql

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'mysql:mysql-connector-java'

JPA

JPA는 한칸 탭이 중요
ddl-auto를 다르게 하면 뭐가 달라지는지
create : 서버를 다시 실행하면 드롭을 하고 다시 만듬
update : 유지

Entity클래스나 등등 다시만들면 create로 바꿔서 다시 갈아엎어야함

캐시 사용 해제


를 입력해 줘야 함

datasource와 같은 줄 그니까 한번 탭키를 눌러줘야함

TEST 코드

junit이라는 자바에서 제공해주는 테스트

테스트 코드는 독립적이어야 한다
테스트 코드 안에서 실행을 하고 가져와야한다

assert가 성공하면 초록체크 아니면 오류

테스트의 3단계

  • given
  1. 새로운 회원을 등록하고 해당 회원의 넘버를 가져옴
    1-1. 테스트용 객체를 생성
    1-2. 테스트용 객체를 DB에 저장
  • when
  1. 위에서 가져온 회원번호를 이용해서 조회
  • then
  1. 1번에서 가입한 회원의 정보와 2번에서 조회한 회원의 정보가 일치 하는지 테스트

일치 확인

import static org.assertj.core.api.Assertions.*;

assertThat(DTO1.get컬럼()).isEqualTo(DTO2.get컬럼());


초록색 체크가 뜨면 성공

@Rollback

@Transactional
@Rollback

Transactional으로 새로운 공간을 만들고 내용을 테스트 한다음에
테스트가 끝나면 Rollback으로 다시 그 부분을 지운다

JPA Spring Data

Repository

Repository를 인터페이스로 만들고 JpaRepository<entity클래스, pk값 타입>을 상속 받는다

where기능


위 처럼 jpa는 정해 놓은 방법대로 만들어야한다

select는 find를 넣고 where의 조건은 by컬럼

두개 이상은 모른다

Optional

Entity타입을 한번 감싸주는 보호막 같은 느낌

Optional<MemberEntity> member = mr.findById(memberId);

MemberEntity member = mr.findById(memberId).get();

jpa에서 테이블을 받을 때는 Optional타입으로 해서 보내준다

Entity타입에 null값이 들어오면 안되니까 그것을 다시 한번 확인하게 해주는?

.get()메서드를 사용해서 Optional에 있는 entity만 가져올 수 있다

테이블 Pk값 가져오기

PK값을 auto increment로 해두면 가져오기 귀찮았는데 이걸 jpa에서는 바로 가져다 준다

save()메서드에 .getId()를 해주면 가져온다

기능

로그인

나머지는 다 비슷하다

리포지토리

컨트롤러

로그인에 성공하면 session에 저장을 하고

실패하면 bindingResult로 다시 html으로 보낸다

서비스

mr.findByMemberEmail()을 이용해서 아이디가 있는지 확인을 하고
null이면 false을 보내고
null이 아니라면 가져온 정보의 password와 입력한 password를 비교한다

html

div 부분이 글로벌 오류를 잡아주는 곳이다

테스트

이메일 체크

서비스

findByMemberEamil()을 했을 때 널이 아니라면 값이 있다는 것이니까 IllegalStateException이라는 예외를 throw한다
throw : 이거는 예외가 발생하면 해당 클래스의 윗단계로 예외를 던진다
IllegalStateException에 "중복이메일 입니다" 를 담아서 컨트롤러로 던지는 것이다

컨트롤러

ms.save()를 try안에 넣고 예외가 오면 그 예외를 bindingResult.reject로 글로벌 오류로 html으로 보낸다

회원전체 조회


jpa에서 회원정보를 가져오면 List에 담아서 준다
리스트에 담아온 entity를 DTO로 변환 시켜서 리스트에 담아서 리턴을 보낸다.

테스트

기타

생성자 생성

@AllArgsConstructor
@NoArgsConstuctor

AllArgsConstuctor은 모든 필드를 매개변수로 사용하는 생성자를 생성
NoArgsConstuctor은 매개변수가 없는 생성자를 생성

IntStream방식

IntSteam.rangeClosed(시작, 끝).forEach( -> {
  코드 내용
});

위 문법을 사용해서 forEach문을 쓰는 방법이 있다

단 숫자를 정해줘야함? 끝 부분에 다른 방법으로 사용하면 되나

throw

이거는 예외가 발생하면 해당 클래스의 윗단계로 예외를 던진다

인텔리제이

기능
sout
soutm
soutp

단축키
컨트롤 D 한줄 복사해서 밑에
컨트롤 알트 L 코드 정리
컨트롤 S 전체 저장
F9 런 디버그?

설정

롬복 사용시

이걸 해야 롬복이 된다고한다
프로그램을 만들 때 마다 해줘야 함

프로그램 내에서 한글 깨짐


help>Edit Custom Vm Options..를 누르면 나오는 파일에
-Dfile.encoding=UTF-8
를 입력해주면 test시 나오는 한글이 깨지지 않는다

DB연동


순서대로 아이디 비밀번호 데이터베이스를 입력하고 Test Connection을 누르면 디비연동 플러그(이거 맞나? 아마도 이거)를 다운 받으라고 뜬다
다운해줘야한다

profile
코딩도전기

0개의 댓글