
1. 로그인 할 때 터지는 것 해결하기
- 원인 : 받을 때 결과값이 없어서 터짐
- 게시글 내부에 try/catch가 내재되어 있을 때
내가 만든 것이 아니니까 직접 제어할 방법 : 위치를 찾아서 직접 try/catch로 묶기
- @Entity
Entity : DB데이터와 같은 테이블을 만들어 줌
반드시 @entity가 걸려있는 class여야 파싱이 됨
데이터 테이블을 Entity에 담아서 민감한 정보들을 DTO에 담아서 전달함
응답 받을 때) object를 리턴하니까 다운 캐스팅해서 받으면 됨
오류가 안나오면 = 어디서 터졌는지 모르면
하나하나 다 번호를 남겨서 실행해서 위치를 찾으면 됨
2. 위치를 찾아서 직접 try/catch로 묶기
public User findByUsernameAndPassword(UserRequest.loginDTO requestDTO) {
Query query = em.createNativeQuery("SELECT * FROM user_tb WHERE username=? AND password=?", User.class); // 알아서 매핑해줌
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
try { // 내부적으로 터지면 터지는 위치를 찾아서 내가 잡으면 됨
User user = (User) query.getSingleResult();
return user;
}catch (Exception e){
return null;
}
컨트롤러 만들 때 책임 다 만들기!
다 만들고 넘어가면 컨트롤러에서 오류가 나지 않음
그렇지 않으면 컨트롤러에서 난 오류를 DB가 출력해 줌
package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class UserController {
// fianl 변수는 반드시 초기화 되어야 함
private final UserRepository userRepository; // null
private final HttpSession session;
public UserController(UserRepository userRepository, HttpSession session) {
this.userRepository = userRepository;
this.session = session;
}
//원래는 get요청이나 예외 post요청하면 됨
//민감한 정보는 쿼리 스트링에 담아보낼 수 없음
@PostMapping("/login")
public String login(UserRequest.LoginDTO requestDTO) {
// 1. 유효성 검사
if(requestDTO.getUsername().length() < 3) {
return "error/400";
}
// 2. 모델 필요 select * from user_tb where username=? and password=?
User user = userRepository.findByUsernameAndPassword(requestDTO); // DB에 조회할때 필요하니까 데이터를 받음
if (user == null) {
return "error/401";
}else {
session.setAttribute("sessionUser", user);
return "redirect:/";
}
}
@PostMapping("/join")
public String join(UserRequest.JoinDTO requestDTO) {
System.out.println(requestDTO);
// 1. 유효성 검사
if (requestDTO.getUsername().length() < 3) {
return "error/400";
}
userRepository.save(requestDTO); // 모델에 위임하기
return "redirect:/loginForm"; //리다이렉션불러놓은게 있어서 다시부른거
}
@GetMapping("/joinForm") // view만 원함
public String joinForm() {
return "user/joinForm";
}
@GetMapping("/loginForm") // view만 원함
public String loginForm() {
return "user/loginForm";
}
@GetMapping("/user/updateForm")
public String updateForm() {
return "user/updateForm";
}
@GetMapping("/logout")
public String logout() {
return "redirect:/";
}
}

3. try/catch 안 하는 이유
- 터트린 것을 잡겠다는 것 → 통신만 이루어지지 않음
insert 시도하기 위한 하드디스크 접촉까지 일어나 IO가 일어남
- DB는 하드디스크에 저장된 데이터를 저장된 문서를 들고 있는 것을 메타 데이터로 적어놓음
안 적어놓으면 직접 찾아가서 넣으려고 하다가 못 넣어서 실패하는 과정 또한 비용이 많이 듦
→ 데이터 사전(메타데이터)같은 것 : 데이터 사서가 확인해서 오류이면 터뜨림
- 경우의 수가 너무 다양해서 에러를 명확하게 판단하기 힘듦
→ try/catch 는 어쩔 수 없는 상황에서 써야 함
4. 유효성 검사를 미리 감지
- try/catch보다 코드를 짜는게 더 좋음!!
- 얘도 조회해야되니까 IO가 일어나긴함
ex) 3명이 오차 없이 정확하게 동시에 접속해서 join요청을 함
각각 3개의 스레드가 생김 → 리쿼스트 객체 2개가 각각 생성
UserController는 메모리에 하나 떠 있음
join이라는 메서드는 호출(실행)시 스택 메모리에 뜸
→ 객체는 1개이나 메서드는 3개가 될 수 있음
동시에 실행되고 독립적인 공간이 생기니까 싱크로나이즈드 할 필요가 없음
DAO도 메서드라 동시에 실행됨
- read는 동시에 가능함
- write가 있는 순간 불가능해짐
ex) 회원가입을 하는데 데이터에 ssar만 있음
셋 다 db에 cos라는 id가 있는지 동시에 요청해서 없는 것을 확인
셋 다 동시에 cos라고 요청하면 두 명은 터지게 됨
→ read는 상관없음 insert때문에 터지는 것
insert는 한 명에게 rock을 걸려서 다른 사람들은 isolation(고립)됨
다른 사람을 느리게 만드는 wait가 걸리니까 최대한 자제하는 것이 좋음
얘 때문에 다른 사람이 rock 걸릴 수가 있으니까 최대한 안 터뜨리는 것이 좋음
Share article