1.User(Package) 리팩토링

1. UserController(바뀐 것 들)
package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@RequiredArgsConstructor // final이 붙은 애들의 생성자를 만들어준다,.
@Controller
public class UserController {
//User에서는 UserService만 사용 할 수 있게 해주는 게 좋다 Borad에서 가져오기 않기!
//트랜잭션관리도 어려워진다.
//간단하게 위임만 하면 된다.
private final UserService userService;
private final HttpSession session;
- private final UserService userService: Java에서 클래스의 필드로 ‘UserService’ 객체를 선언한 코드이다.
- 의존성 주입: ‘UserService’ 객체는 보통 Spring 컨텍스트에 의해 자동으로 주입됩니다. 생성자 주입 방식을 사용하면 ‘UserService’ 필드가 클래스가 인스턴스화될 때 반드시 초기화되도록 보장됩니다.
@PostMapping("/login")
public String login(UserRequest.loginDTO loginDTO) {
// User sessionUser = userRepository.findByUsernameAndPassword(loginDTO.getUsername(),loginDTO.getPassword());
User sessionUser = userService.로그인(loginDTO);
session.setAttribute("sessionUser", sessionUser);
return "redirect:/board";
}
- public String login(UserRequest.loginDTO loginDTO): loginDTO는 사용자로부터 입력받은 로그인 정보(예: 사용자 이름과 비밀번호)를 포함하는 데이터 전송 객체(DTO)입니다.
- User sessionUser = userService.로그인(loginDTO): userService.로그인(loginDTO) 메소드는 로그인 정보를 사용하여 사용자 인증을 처리합니다. 이 메소드는 loginDTO를 기반으로 인증된 User객체를 반환합니다.
- session.setAttribute("sessionUser", sessionUser) : 로그인 성공 후 sessionUser 객체를 세션에 저장하여 이후 요청에서 세션을 통해 사용자 정보를 참조할 수 있습니다. sessionUser"는 세션에서 사용자 정보를 저장하는 키입니다.
//회원가입 하고 난 후
@PostMapping("/join")
public String join(UserRequest.JoinDTO joinDTO) {
//insert 하는 모든 것들은 toEntitiy로 하면 된다.
userService.회원가입(joinDTO);
return "redirect:/login-form";
}
- public String join(UserRequest.JoinDTO joinDTO) : JoinDTO 는 사용자로부터 입력받은 회원가입 정보(예: 사용자 이름, 비밀번호, 이메일 등)를 포함하는 데이터 전송 객체(DTO)입니다. 이 객체는 폼에서 입력된 데이터를 캡슐화하며, 서비스 레이어에서 필요한 데이터를 전달하는 데 사용됩니다
- userService.회원가입(joinDTO) : userService.회원가입(joinDTO) 메소드는 회원가입 정보를 기반으로 회원가입 절차를 처리합니다. userService는 회원가입 비즈니스 로직을 처리하는 서비스 객체입니다. 이 메소드는 보통 DTO를 엔티티로 변환하고, 데이터베이스에 저장하는 작업을 수행합니다.
2. UserRepository(바뀐 것 들)
//유저네임로 조회
public User findByUsername(String username) {
Query query = em.createQuery("select u from User u where u.username=:username", User.class);
query.setParameter("username", username);
try {
User user = (User) query.getSingleResult();
return user;
} catch (Exception e) {
return null;
}
}
- em.createQuery(...): EnitiyManager(em)를 통해 JPQL 쿼리를 생성합니다. select u from User u where u.username=:username 쿼리는User 엔티티에서 username 이 주어진 값과 일치하는 레코드를 조회합니다.
- query.getSingleResult(): 쿼리 결과에서 단일 User객체를 반환합니다. 해당 쿼리가 일치하는 결과를 하나만 반환해야 한다는 것을 의미합니다. getSingleResult()는 결과가 없거나 두 개 이상의 결과가 있을 때 예외를 발생시킬 수 있습니다.
- catch (Exception e): 쿼리 실행 중 발생할 수 있는 예외를 잡아내어, 예외가 발생하면 null을 반환합니다.
//401 터트리기 여기서 터트리기
public User findByUsernameAndPassword(String username, String password) throws NoResultException {
Query query = em.createQuery("select u from User u where u.username=:username and u.password=:password", User.class);
query.setParameter("username", username);
query.setParameter("password", password);
try {
User user = (User) query.getSingleResult();
return user;
} catch (Exception e) {
// e.getmsg는 해주면 안된다. 서버 노출이 된다.
throw new Exception401("인증되지 않았습니다.");
}
}
- 주어진 코드는 사용자 인증을 위한 메소드 findByUsernameAndPassword 입니다. 이 메소드는 사용자 이름과 비밀번호를 기반으로 사용자 정보를 조회합니다.
3. UserService(바뀐 것들)
package shop.mtcoding.blog.user;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import shop.mtcoding.blog.core.error.ex.Exception400;
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
@Transactional
//비정상 로직만 if에 넣어서 걸러내라!! if, else로 해버리면 가독성이랑 로직이 더 길어진다....
public void 회원가입(UserRequest.JoinDTO joinDTO){
User oldUser = userRepository.findByUsername(joinDTO.getUsername());
if(oldUser != null){
throw new Exception400("이미 존재하는 유저네임입니다.,");
}
userRepository.save(joinDTO.toEntity());
}
- userRepository.findByUsername(joinDTO.getUsername()) : 사용자 이름으로 기존 사용자 정보를 조회합니다. userRepository는 JPA 레포지토리로, 데이터베이스에서 User 엔티티를 관리합니다.
- if (oldUser != null) : 사용자가 이미 존재하는 경우 예외를 발생시킵니다. 이로 인해 동일한 사용자 이름으로 가입할 수 없도록 합니다.
- userRepository.save(joinDTO.toEntity()): joinDTO를 User 엔티티로 변환한 후, 새로운 사용자 정보를 데이터베이스에 저장합니다. toEntity() 메소드는 JoinDTO 객체를 User 엔티티로 변환하는 역할을 합니다.
@Transactional
public User 로그인(UserRequest.loginDTO loginDTO) {
User user = userRepository.findByUsernameAndPassword(loginDTO.getUsername(), loginDTO.getPassword());
return user;
}
- userRepository.findByUsernameAndPassword(...) : userRepository는 JPA 레포지토리로, findByUsernameAndPassword 메소드를 사용하여 데이터베이스에서 사용자 이름과 비밀번호가 일치하는 사용자 정보를 조회합니다. 이 메소드는 비밀번호와 사용자 이름이 정확히 일치하는 사용자 정보를 반환합니다.
2. Board(Package)리팩토링
1. BoardRepository(바뀐 것들)
//Board class 자동으로 오브젝트 맵핑을 해준다.
public Board findById(int id) {
// select * from board_tb bt inner join user_tb ut on bt.user_id = ut.id where bt.id =1
Query query = em.createQuery("select b from Board b join fetch b.user where b.id = :id", Board.class);
query.setParameter("id", id);
try {
// 단일 결과 조회
Board board = (Board) query.getSingleResult();
return board;
} catch (Exception e) {
e.printStackTrace();//오류 제대로 볼 수 있는 코드
//내가 예외를 설정 할 수 있다. 익세션을 내가 잡은것 까지 배움 - 처리 방법은 v2에서 배우기
//자기가 처리 하기 싫으면 throw로 넘길 수 있다.
throw new Exception400("게시글 아이디를 찾을 수 없습니다.");
}
}
2. BoardService(바뀐것들)
@Transactional
public void 게시글쓰기(BoardRequest.SaveDTO saveDTO, User sessionUser) {
boardRepository.save(saveDTO.toEntity(sessionUser));
}
Share article