지금 까지의 내용
수업내용 | 언어 | 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와 연동한다
기준 | 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(Representational State Transfer) API(Application Programming Interface)
기능 | 기존 방식 | - | 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를 사용한다
<html lang="en" xmlns:th="http://www.thymeleaf.org">
html 위에 언어 설정부분을 이걸로 교체하면 타임이프로 바뀐다
컨트롤러
html
실행화면
th:object="${모델로 받은 이름}"
th:field="${필드 이름}"
설정
순서
그리들의 디펜던씨에
implementation 'org.springframework.boot:spring-boot-starter-validation'
@Validated
유효성 검증 기능
BindingResult
오류를 담아서 보내주는 기능
글로벌 오류를 보내주는 신기한 친구?
컨트롤러
html
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}]])"로 데이터를 [[]] 로 묶어줘야한다
묶었을 때 끝에 괄호에서 오류가 나오는데 무시해도 되는 오류이다
const 변수를 만들어서 "/member/"+(가져온 데이터)를 해서 ajax용 url을 만들자
기존 했던 ajax에서 data만 빠진 모습이다
data에서 사용했던 번호를 url으로 넘겼으니 data는 할 일이 없어서 해고 당했다 ㅠ
컨트롤러
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 : 길이 지정, 유니크지정
필드 값에 _(언더바)넣으면 안됨
static 메서드 사용
팩토리 메서드
이유
entity클래스의 생성자를 노출하지 않도록 함
가독성 있는 이름을 줄 수 있음
생성자는 리턴을 줄 수 없지만 메서드는 리턴도 가능
(DI, Dependency Injection)
@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{}
final이 붙은 변수만 롬복을 사용하게 해줌
final을 붙임으로서 더 오타를 줄여준다
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'mysql:mysql-connector-java'
JPA는 한칸 탭이 중요
ddl-auto를 다르게 하면 뭐가 달라지는지
create : 서버를 다시 실행하면 드롭을 하고 다시 만듬
update : 유지
Entity클래스나 등등 다시만들면 create로 바꿔서 다시 갈아엎어야함
를 입력해 줘야 함
datasource와 같은 줄 그니까 한번 탭키를 눌러줘야함
junit이라는 자바에서 제공해주는 테스트
테스트 코드는 독립적이어야 한다
테스트 코드 안에서 실행을 하고 가져와야한다
assert가 성공하면 초록체크 아니면 오류
import static org.assertj.core.api.Assertions.*;
assertThat(DTO1.get컬럼()).isEqualTo(DTO2.get컬럼());
초록색 체크가 뜨면 성공
@Transactional
@Rollback
Transactional으로 새로운 공간을 만들고 내용을 테스트 한다음에
테스트가 끝나면 Rollback으로 다시 그 부분을 지운다
Repository를 인터페이스로 만들고 JpaRepository<entity클래스, pk값 타입>을 상속 받는다
위 처럼 jpa는 정해 놓은 방법대로 만들어야한다
select는 find를 넣고 where의 조건은 by컬럼
두개 이상은 모른다
Entity타입을 한번 감싸주는 보호막 같은 느낌
Optional<MemberEntity> member = mr.findById(memberId);
MemberEntity member = mr.findById(memberId).get();
jpa에서 테이블을 받을 때는 Optional타입으로 해서 보내준다
Entity타입에 null값이 들어오면 안되니까 그것을 다시 한번 확인하게 해주는?
.get()메서드를 사용해서 Optional에 있는 entity만 가져올 수 있다
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은 매개변수가 없는 생성자를 생성
IntSteam.rangeClosed(시작, 끝).forEach( -> {
코드 내용
});
위 문법을 사용해서 forEach문을 쓰는 방법이 있다
단 숫자를 정해줘야함? 끝 부분에 다른 방법으로 사용하면 되나
이거는 예외가 발생하면 해당 클래스의 윗단계로 예외를 던진다
기능
sout
soutm
soutp
단축키
컨트롤 D 한줄 복사해서 밑에
컨트롤 알트 L 코드 정리
컨트롤 S 전체 저장
F9 런 디버그?
이걸 해야 롬복이 된다고한다
프로그램을 만들 때 마다 해줘야 함
help>Edit Custom Vm Options..를 누르면 나오는 파일에
-Dfile.encoding=UTF-8
를 입력해주면 test시 나오는 한글이 깨지지 않는다
순서대로 아이디 비밀번호 데이터베이스를 입력하고 Test Connection을 누르면 디비연동 플러그(이거 맞나? 아마도 이거)를 다운 받으라고 뜬다
다운해줘야한다