나는 계층형 구조를 이용해 프로젝트를 진행할 생각이었다. Repository는 JPA를 직접 사용하게 되는 계층으로, Entity Manager를 사용한다. Service는 비즈니스 로직을 작성할 공간이고 트랜잭션을 처리할 부분이기도 하다.
먼저 JPA에서 Repository임을 알 수 있게, 컴포넌트 스캔으로 스프링빈으로 등록하도록 @Repository 어노테이션을 선언해준다. 자바 코드를 직접 입력해 컴포넌트 스캔을 할 수 있지만 롬복을 이용하면 어노테이션 하나로 코드를 간추릴 수 있다. 그리고 엔티티 매니저를 선언하고 @PersistenceContext로 주입받는다.
제일 첫번째 기능은 당연하게도 회원정보 저장이기 때문에 세이브 메서드를 만들어준 후 유저 객체를 파라미터로 받고 받은 유저 엔티티를 persist해준다. EntityManager가 persist를 해주면 그 엔티티가 DB가 아닌 먼저 영속성 컨텍스트에 저장이 된다. JPA는 영속성 컨텍스트에 먼저 저장이 되고 커밋이 되는 시점에 데이터를 넣는 방식을 사용한다. 그래서 영속성 컨텍스트는 쉽게 말해 "JPA가 관리해주는 간이저장소" 같은 느낌이다. 그래서 커밋이 날라가기 전까지 JPA가 데이터를 관리해준다.
그 외 메서드는 findAll, findTeachers, findStudents, findLoginId 등이 있었다. 이름 그대로 find 뒤에 붙은 데이터를 조건으로 쿼리문을 날려서 리스트를 받는 메서드이다. JPA는 자동으로 쿼리를 생성해주기도 하지만 조회하는 쿼리는 직접 작성하는 것이 제일 보기가 편한 것 같아 createquery 함수를 사용해 직접 쿼리를 작성해주었다. JPQL은 특이한 문법을 사용한다. 테이블을 기준으로 하는게 아닌 객체를 기준으로 작성해야한달까 ..
return em.createQuery("select u from User u where u.loginId = :loginId and u.loginPw = :loginPw", User.class)
이런식으로 from절에서 테이블명이 아닌 엔티티명으로 선언을 해주어야 한다. 그리고 : loginId나 : loginPw는 파라미터로 데이터를 넣어주기 위함이다.
.setParameter("loginId", loginId)
.setParameter("loginPw", loginPw)
.getResultList();
그래서 추가로 이런 식으로 파라미터를 달아줘야한다. 마지막에 붙은 .getResultList는 말 그대로 결과를 리스트로 받겠다는 뜻이다.
UserService도 컴포넌트 스캔으로 스프링빈에 등록하기 위해 @Service 어노테이션을 작성해주고, 트랜잭션을 처리해야하기 때문에 @Transactional 어노테이션을 선언해준다. 여기서는 데이터 변경보단 읽는 메서드가 많을 것 같아 기본 세팅을 readOnly를 true로 해주었다. readOnly를 true로 해주게 되면 조금이나마 성능 향상을 노릴 수 있다. @RequiredArgsConstructor 어노테이션을 작성해준다. 이 어노테이션은 생성자 주입을 자동으로 해주는 어노테이션이다.
회원가입 메서드를 작성해준다. 회원가입을 할 때에는 아이디 중복체크를 해야하기 때문에 따로 중복체크 메서드를 작성하여 리포지토리에서 작성했던 findLoginId 메서드를 사용해 사용자가 입력한 LoginId가 있는지 확인하고 리스트가 있다면 Exception을 날리고, 리스트가 비었다면 그대로 리포지토리의 세이브 메서드를 사용해 저장해준다.
@Transactional(readOnly = false)
public Long register(User user) {
List<User> findDoubleCheck = doublecheckLoginId(user.getLoginId());
if (!findDoubleCheck.isEmpty()){
throw new IllegalStateException("Id already exists");
}
userRepository.save(user);
return user.getId();
}
패스워드는 암호화를 해서 DB에 저장해야 하기 때문에 SHA-256 기법을 사용할 것이다. 그래서 파라미터로 받은 문자열을 암호화시켜주는 메서드를 하나 만들었다.
그 외엔 리포지토리에서 만든 조회 메서드를 위임받는 메서드밖에 없으므로 생략해야겠다.
후기
강의를 보면서 해서 비슷한 부분이 많았지만 그래도 새로운 언어를 배우는 것을 끊을 수 없는 이유가 이 부분을 진행하면서 다시금 느꼈다. 다 비슷비슷한 언어 같지만 보다보면 조금씩 다른 부분이 보이기 시작하고 새로운 개념들을 배워가면서 내가 성장한다는 느낌을 받는게 너무 재미있고 좋다.
'개발일지_development diary > YSit' 카테고리의 다른 글
YSit [7] - UserController 개발하기 (0) | 2022.12.24 |
---|---|
YSit [6] - 유저 기능 테스트하기 (0) | 2022.12.24 |
YSit [4] - 엔티티 개발하기 (0) | 2022.12.24 |
YSit [3] - IntelliJ 프로젝트 생성 & 설정하기 (2) | 2022.12.24 |
YSit [2] - 도메인 설계하기 (0) | 2022.12.23 |