
1. View 보기

{{> /layout/header}}
<div class="container p-5">
<!-- 요청을 하면 localhost:8080/login POST로 요청됨
username=사용자입력값&password=사용자값 -->
<div class="card">
<div class="card-header"><b>로그인을 해주세요</b></div>
<div class="card-body">
<form action="/login" method="post" enctype="application/x-www-form-urlencoded">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter username" name="username" value="ssar">
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="Enter password" name="password" value="1234">
</div>
<button type="submit" class="btn btn-primary form-control">로그인</button>
</form>
</div>
</div>
</div>
{{> /layout/footer}}
JPQL을 사용하면 좋은 점 : DB가 변경되어도 쿼리를 바꿀 일이 없음
2. UserRepository 에 findByUsernameAndPassword() 만들기
package shop.mtcoding.blog.user;
import jakarta.persistence.EntityManager;
import jakarta.persipackage shop.mtcoding.blog.user;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@RequiredArgsConstructor
@Repository
public class UserRepository {
private final EntityManager em;
public User findByUsernameAndPassword(UserRequest.LoginDTO reqDTO){
Query query =
em.createQuery("select u from User u where u.username = :username and u.password =:password", User.class);
query.setParameter("username", reqDTO.getUsername());
query.setParameter("password", reqDTO.getPassword());
return (User) query.getSingleResult();
}
}
stence.Query;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@RequiredArgsConstructor
@Repository
public class UserRepository {
private final EntityManager em;
public User findByUsername(String username){
Query query = em.createQuery("select u from User u where u.username = :username", User.class);
query.setParameter("username", username);
return (User) query.getSingleResult();
}
}
- 단위 테스트하기
- @Repository : new해서 IoC컨테이너에 등록됨
BoardController가 Repository에 의존함 → IoC컨테이너에서 원래 생성자로 주입 됨
컴포넌트 스캔
등록이 안됨 : 디폴트 생성자가 없기 때문에 new를 못 함
매개변수 하나를 받는 생성자만 있기 때문에 IoC에서 Repository를 찾아서 주입해줌
의존성 주입
- 인수를 넣어줘야 함 : 생성자 대신 final을 적으면 됨
java는 클래스의 상태 변수가 final이면 생성시에 초기화가 되어야 함
- @RequiredArgsConstructor : final이 붙은 생성자를 만들어 줌
- UserRepositoryTest는 new가 안되서 @Autowired가 의존성 주입을 해줌 → final을 안붙여도 됨
- @DataJpaTest는 Datasource(connection pool), EntityManager(PC 관리)
단위 테스트 : DB만 테스트 하는 것
통합 테스트 : 필요한 걸 다 띄우는 것
package shop.mtcoding.blog.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import shop.mtcoding.blog.user.User;
import shop.mtcoding.blog.user.UserRepository;
import shop.mtcoding.blog.user.UserRequest;
@Import(UserRepository.class) // IoC 등록코드
@DataJpaTest // Datasource(connection pool), EntityManager
public class UserRepositoryTest {
@Autowired // DI
private UserRepository userRepository;
@Test
public void findByUsername_test(){
// given
UserRequest.LoginDTO reqDTO = new UserRequest.LoginDTO();
reqDTO.setUsername("ssar");
reqDTO.setPassword("1234");
// when
User user = userRepository.findByUsernameAndPassword(reqDTO);
// then
}
}
2. UserRequest 만들어서 LoginDTO 만들기
package shop.mtcoding.blog.user;
import lombok.Data;
public class UserRequest {
@Data
public static class LoginDTO{
private String username;
private String password;
}
}
3. UserController 에 login 만들기
package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@RequiredArgsConstructor
@Controller
public class UserController {
private final UserRepository userRepository;
private final HttpSession session;
@PostMapping("/login")
public String login(UserRequest.LoginDTO reqDTO) {
User sessionUser = userRepository.findByUsernameAndPassword(reqDTO);
session.setAttribute("sessionUser", sessionUser);
return "redirect:/";
}
@GetMapping("/join-form")
public String joinForm() {
return "user/join-form";
}
@GetMapping("/login-form")
public String loginForm() {
return "user/login-form";
}
@GetMapping("/user/update-form")
public String updateForm() {
return "user/update-form";
}
@GetMapping("/logout")
public String logout() {
return "redirect:/";
}
}


4.
package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@RequiredArgsConstructor
@Controller
public class UserController {
private final UserRepository userRepository;
private final HttpSession session;
@PostMapping("/login")
public String login(UserRequest.LoginDTO reqDTO) {
User sessionUser = userRepository.findByUsernameAndPassword(reqDTO);
session.setAttribute("sessionUser", sessionUser);
return "redirect:/";
}
@GetMapping("/join-form")
public String joinForm() {
return "user/join-form";
}
@GetMapping("/login-form")
public String loginForm() {
return "user/login-form";
}
@GetMapping("/user/update-form")
public String updateForm() {
return "user/update-form";
}
@GetMapping("/logout")
public String logout() {
session.invalidate();
return "redirect:/";
}
}

Share article