[Spring Boot] V-RIS 개발 일지(2) - MySQL 연동, Spring Data JPA를 이용한 간단한 회원 관리 시스템 및 오류 수정

Spring Boot와 MySQL 연동 📡

우선 spring 프로젝트를 만들고 MySQL과의 연동을 위해 아래의 dependency를 build.gradle에 추가해준다.

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'mysql:mysql-connector-java'

그 후 application.properties에 아래의 코드를 추가한다.

server.address=localhost
server.port=8080 #서버는 8080 port를 이용

#db_name에 로컬 DB명을 기입
spring.datasource.url=jdbc:mysql://localhost:3306/db_name?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root # 사용자 아이디
spring.datasource.password=1234 # 사용자 비밀번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# mysql 연동
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

#DB의 고유 기능 사용 가능
spring.jpa.hibernate.ddl-auto=create

logging.level.org.hibernate=info

# Hibernate에서의 SQL문 확인 가능
spring.jpa.properties.hibernate.show_sql=true
# Hibernate에서의 SQL문의 가독성을 증가
spring.jpa.properties.hibernate.format_sql=true

spring.jpa.properties.hibernate.use_sql_comments=true

spring.jpa.hibernate.ddl-auto=[ ]

  • create : 기존 테이블을 삭제하고 새로 생성 [ DROP + CREATE ]
  • create-drop : CREATE 속성에 추가로 어플리케이션을 종료할 때 생성한 DDL을 제거 [ DROP + CREATE + DROP ]
  • update : DB 테이블과 엔티티 매핑 정보를 비교해서 변경 사항만 수정 [ 테이블이 없을 경우 CREATE ]
  • validate : DB 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 어플리케이션을 실행하지 않음
  • none : 자동 생성 기능을 사용하지 않음

이제 IntelliJ의 database에서 연결이 됐는 지 확인해본다!

위와 같이 연결 정보를 입력했을 때 Test Connection에서 Succeeded가 뜬다면 연결이 잘 된것이다.

Spring Data JPA를 이용한 회원 관리 📃

일단 DB에 저장될 table을 생성해야 한다. 직접 sql코드로도 생성할 수 있지만 필자는 User 클래스에서 @Entity를 사용해 User클래스와 table을 매핑해보려고 한다.

User

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name="user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer userIdx;

    @Column(name = "userId")
    private String userId;

    @Column(name = "userPwd")
    private String userPwd;

    @Column(name = "email")
    private String email;

    @Column(name = "veganLevel")
    private Integer veganLevel;
}

@Entity를 이용해 각 멤버변수들을 table의 컬럼과 연결시켜주었다.
아래는 userIdx에 사용된 어노테이션이다.

  • @Id: 프라이머리 키로 등록
  • @GeneratedValue: 자동 생성을 해주는 값, MySQL의 AUTO_INCREMENT 방식을 이용

UserRepository

Spring Data JPA에서는 JPA의 구현체인 Hibernate를 이용하기 위한 여러 API를 제공하는데, 그 중 한 개가 JPARepository이다.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

}

단순히 JpaRepository를 상속받는 것만으로도 끝나며 인터페이스 내에 추가적인 메서드도 당연히 작성 가능하다. @Repository를 추가하여 Controller에서 의존성 주입을 할 수 있게 설정한다.
JpaRepository를 상속받을 것으로 단순한 작업은 sql없이 CRUD작업을 할 수 있다.

UserJpaController

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.validation.Valid;
import java.net.URI;
import java.util.List;
import java.util.Optional;

@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/vegan-res")
public class UserJpaController {

    @Autowired
    private UserRepository userRepository;

    // 전체 사용자 조회
    @GetMapping("/users")
    public List<User> retrieveAllUsers() {
        return userRepository.findAll();
    }


    // 개별 사용자 조회
    @GetMapping("/users/{id}")
    public User retrieveUser(@PathVariable int id){
        Optional<User> user = userRepository.findById(id);

        if(!user.isPresent()){
            throw new UserNotFoundException(String.format("ID[%s] not found", id));
        }

        return user.get(); // .get()은 Optional에서 가져옴
    }

    // 사용자 추가(회원 가입)
    @PostMapping("/users")
    public ResponseEntity<User> createUser(@Valid @RequestBody User user)
    {
        User savedUser = userRepository.save(user);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(savedUser.getUserIdx()) 
                .toUri(); // Uri화 함

        return ResponseEntity.created(location).build();
    }
    // 회원 정보 수정
    @PutMapping("/users/{id}")
    public ResponseEntity<User> updateUser(@PathVariable int id, @RequestBody User user) {
        Optional<User> optionalUser = userRepository.findById(id);

        if (!optionalUser.isPresent()) {
            throw new UserNotFoundException(String.format("ID[%s} not found", id));
        }

        User storedUser = optionalUser.get();
        ///수정할 정보 입력
        storedUser.setUserId(user.getUserId());
        storedUser.setUserPwd(user.getUserPwd());
        storedUser.setVeganLevel(user.getVeganLevel());
        storedUser.setEmail(user.getEmail());

        User updatedUser = userRepository.save(storedUser);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(updatedUser.getUserIdx())
                .toUri();

        return ResponseEntity.created(location).build();
    }
    //회원 탈퇴
    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable int id) {
        userRepository.deleteById(id);
    }
}

이로써 간단한 회원 관리에 필요한 CRUD작업을 할 API들을 구현해봤다!!

PostMan을 이용한 테스트

유저 정보 생성(create)

유저 정보 조회(read)

유저 정보 수정(update)

유저 정보 삭제(delete)

최종 결과


삭제가 되어 찾을 수 없다는 404 not found를 출력!

오류 수정 ✂

Domain, Controller, Repository 모두 만들고 실행을 하려 했는데 자꾸 위의 사진과 같은 오류가 뜨길래 혼자는 해결하지 못해 팀원에게 도움을 받아 해결을 했다... 이유는

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

application.properties에 추가한 이 코드 한 줄 때문이었는데,,, 이것때문에 자꾸 Controller에서 Repository를 찾지 못했었다 ㅠㅠ 필자와 같은 고생을 하지 않길 바라며 개발일지를 마친다,,,

좋은 웹페이지 즐겨찾기