이전 글에서 프로젝트 생성 과정을 보여드렸으니 이제 본격적으로 개발에 들어가겠습니다.
(지난 게시글 보러가기)
팀원과의 회의를 통해 우선 회원가입 서비스를 개발하기로 했습니다.
'안드로이드' 에서 회원정보를 JSON형태로 보내주면 '서버' 에서 받아 DB에 저장해주는 방식으로 개발해보겠습니다.
JPA, MySQL, Servlet을 토대로 코드를 작성할 것이고 JPA는 start.spring.io에서 따로 dependency 추가를 해줬으니
남은 MySQL 세팅을 해보겠습니다.
(따라 해보실 분은 Maven프로젝트인 부분 참고해주세요!)
MySQL 세팅
MySQL을 사용하기 위해 pom.xml에 dependency를 추가.
pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
다음으로 application.properties에 아래 양식에 맞춰 코드 작성하면 DB연결 성공.
application.properties
# DataSource
spring.datasource.url=jdbc:mysql://localhost:3306/[DB이름]?autoReconnect=true
spring.datasource.username=[사용자이름]
spring.datasource.password=[DB비밀번호]
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
DTO 생성
내가 프론트에서 받을 정보는 [UID, 메일주소, 로그인타입, 닉네임] 이다.
이걸 토대로 테이블을 작성해보자.
CREATE TABLE BASE_USER (
uid VARCHAR(100) PRIMARY KEY,
email VARCHAR(50),
logintype VARCHAR(10) NOT NULL,
nickname VARCHAR(50) NOT NULL
);
유일성이 확보되는 UID를 PRIMARY KEY로 지정했으며,
로그인 타입은 카카오,페이스북,구글 로그인 API를 사용할 것이라 구분을 위해 사용할 것이다.
(카카오는 이메일 입력이 선택사항이라 NOT NULL을 빼주었습니다.)
참고로 인덱스 구성은 PRIMARY KEY를 맨 위에 두는 것이 효율적이다.
자 이제 DB와 같은 형태로 DTO를 생성해보자
User.java
@Getter @Setter
@ToString
@Table(name = "BASE_USER")
@Entity
public class User {
@Id
private String uid;
@Column(length = 50, nullable = true)
private String email;
@Column(length = 10, nullable = false)
private String logintype;
@Column(length = 50, nullable = false)
private String nickname;
}
Getter Setter를 직접 작성해주는 방식을 버리고 Lombok을 사용해서 어노테이션 형태로 코드를 작성했다.
덕분에 코드가 훨씬 짧아지고 보기 깔끔하다. 그 외에 @Table, @Id, @Column 어노테이션도 이용해서
쉽고 보기편하게 DTO를 작성해보았다.
@Table(name = "테이블명") : DB에서 사용하는 Table 선택
@Id : sql의 PRIMARY KEY와 같은 기능
@Column() : 컬럼의 속성 설정
UserRepository, UserService 생성
이제 DB에 User 정보를 저장하기 위해 UserRepository와 UserService를 만들어야한다.
우선 어떤 클래스를 작성하든 먼저 Interface를 작성해주는 것이 첫번째이다.
UserRepository라는 이름의 인터페이스를 생성한다.
UserRepository.java
public interface UserRepository {
void save(User user);
Optional<User> findByEmail(String email);
List<User> findAll();
}
세 가지 기능을 추가할 수 있도록 인터페이스를 세팅했다.
save(User): User정보 DB에 저장
findByEmail(String): 이메일을 통해 유저데이터 검색 (해당 이메일의 유저가 없는 상황을 고려해 Optional로 작성)
findAll(): 모든 유저 검색
이제 UserRepository를 implements할 파일을 작성하자.
JpaUserRepository.java
@Repository
public class JpaUserRepository implements UserRepository {
private final EntityManager em;
@Autowired
public JpaUserRepository(EntityManager em){
this.em = em;
}
@Override
public void save(User user) {
em.persist(user);
}
@Override
public Optional<User> findByEmail(String email) {
User user = em.find(User.class, email);
return Optional.ofNullable(user);
}
@Override
public List<User> findAll() {
return em.createQuery("select m from BASE_USER m", User.class)
.getResultList();
}
}
스프링 컨테이너에 Repository로 등록하기 위해 @Repository 어노테이션을 사용했다.
또한 JPA 사용을 위해 Entity Manager(em) 생성은 필수다.
스프링 컨테이너에 싱글톤으로 생성하여 관리할 것이기 때문에 @Autowired 처리 해주었다.
save기능은 em.persist(user)만 입력하면
@Table(name = "BASE_USER")
아까 입력했던 @Table 어노테이션이 table을 찾아 알아서 저장해준다. JPA는 너무 편리한 기능인 것 같다.
email을 통해 User를 찾아오는 기능 또한 em.find로 해결했다.
마지막으로 findAll은 JPA 쿼리문을 작성하여 .getResultList() 함수로 List형태로 반환받았다.
(em.createQuery()를 통해 작성할 수 있습니다.)
이제 UserService를 작성하여 repository를 사용해보자
UserService는 추후에 딱히 변경될 부분이 아니기 때문에 인터페이스 생성을 생략했다.
UserServiceImpl.java
@Service
@Transactional
public class UserServiceImpl {
private UserRepository userRepository;
@Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
//user데이터 DB에 저장
public void join(User user){
userRepository.save(user);
}
//email주소로 db에서 유저데이터 검색
public Optional<User> findUserByEmail(String email){
return userRepository.findByEmail(email);
}
public List<User> findUsers(){
return userRepository.findAll();
}
}
스프링 컨테이너에 Service객체로 등록하기 위해 @Service 어노테이션을 사용했다.
아래에는 @Transactional 어노테이션을 사용했는데 이 어노테이션은 트렌젝션이 발생하고 종료되는 클래스에 필수적으로 적어주어야 오류가 나지 않는다.
이 클래스 같은 경우는 UserRepository.save() 함수 내부의 em.persist() 로 인해 트렌젝션이 발생하므로 적어주었다.
또한 UserRepository는 스프링 컨테이너에서 스프링 빈을 받아와 싱글톤으로 사용할 것이기 때문에 @Autowired 처리 해주었다.
이제 이 UserRepository를 사용해 기능들을 구현하면 Service 구현도 끝이다.
마지막으로 스프링 컨테이너에 스프링 빈으로 이들을 등록하기 위한 Config와, Servlet Controller만 만들면 끝이난다.
글이 너무 길어지니 다음 게시글에서 이어가겠다.
'프로젝트' 카테고리의 다른 글
[SpringBoot] [어따세워] Amazon S3와 @RestController를 이용해 리뷰 기능 구현하기(2) - Review Upload 기능 개발 (2) | 2022.01.03 |
---|---|
[SpringBoot] [어따세워] 전화번호로 주차장 찾기 기능 추가! (2) | 2021.12.14 |
[SpringBoot] [어따세워] Servlet, JPA, MySQL 이용해서 회원가입 서비스 만들기!(2) (2) | 2021.12.06 |
[어따세워] 메타버스 스터디룸 (Gather town) (0) | 2021.11.30 |
[SpringBoot] [어따세워] 첫 백엔드 프로젝트 기획 (2) | 2021.11.29 |