Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

Super Coding Addict

어드민 페이지 만들기 (2) 본문

Spring Boot 웹개발

어드민 페이지 만들기 (2)

밍응애 2021. 2. 4. 00:03

* build.gradle에 의존성 추가

- JPA와 mysql연결을 위한 의존성 추가하기

dependencies{
  compile('org.springframework.boot:spring-boot-starter-data-jpa')
  compile('mysql:mysql-connector-java')
}

 

* JPA

- ORM (Object Relational Mapping)

- DB정보를 객체지향으로 손쉽게 활용할 수 있게 해줌

- 쿼리보단 객체에 집중할 수 있게 해줌

 

# MySQL에서 생성한 user테이블

 

# com.example.study.model.entity 패키지 > entity 클래스

package com.example.study.model.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

import javax.persistence.*;
import java.time.LocalDateTime;

@Data
@AllArgsConstructor
@Entity // == table
//@Table(name = "user")   //class이름 == DB Table이름 이라면 JPA에서 자동매칭해줌
public class User {
    @Id //식별자
    @GeneratedValue(strategy = GenerationType.IDENTITY) //어떤식으로 관리할 것인지에 대한 전략옵션
    private Long id;

    //@Column(name = "account")   //변수명 == column 이름 동일하다면 자동매칭
    private String account;

    private String email;

    private String phoneNumber;

    private LocalDateTime createdAt;

    private String createdBy;

    private LocalDateTime updatedAt;

    private String updatedBy;

    public User() {

    }
}

--> @Entity : 해당 class가 Entity임을 명시

--> @Table : 실제 DB테이블의 이름을 명시, 그러나 DB테이블 이름과 class이름이 같다면 굳이 쓸 필요 X

--> @Id : Index primary key를 명시

--> @Column : 실제 DB column의 이름 명시, 그러나 변수명이 DB 컬럼명과 같다면 굳이 쓸 필요 X

--> @GeneratedValue : Primary key 식별키의 전략 설정

--> 이 클래스에서 자바로 선언한 변수들은 DB에서 Snake Case로 선언한 컬럼명을 Camel Case로 써주면 JPA 라이브러리가 알아서 이를 매칭해준다

 

# com.example.study.repository패키지 - UserRepository 인터페이스

package com.example.study.repository;

import com.example.study.model.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
//따로 쿼리문 작성하지 않아도 기본적인 CRUD 실행가능
public interface UserRepository extends JpaRepository<User, Long> {
    
}

--> 이 UserRepository 인터페이스는 JpaRepository클래스를 상속하므로, 쿼리문 작성 없이 기본적인 CRUD 실행을 가능하게 한다

--> JpaRepository<T, ID>이므로 T에는 제네릭타입으로 Entity인 User형을, ID에는 index primary key에 해당하는 id의 타입인 Long형으로 선언

 

# 이제, CRUD를 테스트해보자

# src > test > java - com.example.study.repository패키지 > UserRepositoryTest 클래스

 

package com.example.study.repository;

import com.example.study.StudyApplicationTests;
import com.example.study.model.entity.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.Optional;

public class UserRepositoryTest extends StudyApplicationTests {
    //Dependency Injection (DI)
    //DI의 핵심은 싱글톤(단 한번만 생성)
    @Autowired
    private UserRepository userRepository;

    @Test
    public void create(){
        User user = new User();
        //user.setId();
        user.setAccount("TestUser03");
        user.setEmail("TestUser03@gmail.com");
        user.setPhoneNumber("010-1111-3333");
        user.setCreatedAt(LocalDateTime.now());
        user.setCreatedBy("TestUser3");

        User newUser = userRepository.save(user);
        System.out.println("newUser : " + newUser);
    }

--> 테스트를 할 때는 @Test 어노테이션을 달아준다

--> 테스트를 하고자하는 UserRepository 클래스를 @Autowired로 의존성 주입해준다. User 객체는 매번 들어있는 변수의 값들이 달라지므로 필요할 때마다 객체를 생성해서 쓰는 것과 달리 UserRepository클래스는 한번만 생성하는 싱글톤이다

--> CRUD의 C(Create)를 테스트, 이 때 userRepository.save(user)를 하면 User형 객체가 반환된다

 

@Test
    public void read(){
        Optional<User> user = userRepository.findById(2L);

        user.ifPresent(selectUser ->{
            System.out.println("user : " + selectUser );
            System.out.println("email : " + selectUser.getEmail());
        });
    }

--> CRUD의 R(Read)를 테스트

--> userRepository가 JpaRepository를 상속하였기에 findById메서드를 사용할 수 있고, id값으로 데이터를 찾을 수 있다

--> 이 때, 해당 id가 테이블에 없다면 null값이 반환될 수도 있기에 Optional을 쓴다

 

 @Test
    public void update(){
        Optional<User> user = userRepository.findById(2L);

        user.ifPresent(selectUser ->{
            selectUser.setAccount("PPPP");
            selectUser.setUpdatedAt(LocalDateTime.now());
            selectUser.setUpdatedBy("update method()");

            userRepository.save(selectUser);

        });
    }

--> CRUD의 U(Update)를 테스트

--> 우선 findById로 데이터를 찾는다 -> 테이블안에 해당 id가 있어서 user에 값이 있다면(user.ifPresent), selectUser로 다시 그 값을 가져 온 뒤 -> 그 값들 중 update요청이 된 값들만 setter로 값을 수정한다

 

@Test
@Transactional
    public void delete(){
        Optional<User> user = userRepository.findById(1L);

        Assertions.assertTrue(user.isPresent());

        user.ifPresent(selectUser->{
            userRepository.delete(selectUser);
        });

        Optional<User> deleteUser = userRepository.findById(1L);

        Assertions.assertFalse(deleteUser.isPresent());
    }

--> CRUD에서 D(Delete)를 테스트

--> @Transactional 어노테이션을 달아주면, 실제 DB에서 일어나는 것처럼 테스트를 수행하여 결과값을 보여주지만 실제 DB에 결과를 저장X

--> Assertions.assertTrue : 예상되는 값이 True

--> Assertions.assertFalse: 예상되는 값이 False

--> 여기서는 Delete를 수행하고 나면 id값이 1L인 데이터는 없으므로, deleteUser.isPresent()를 하면 false가 나온다

'Spring Boot 웹개발' 카테고리의 다른 글

어드민 페이지 만들기 (1)  (0) 2021.02.02
회원 관리 예제 (1)  (0) 2021.01.31
스프링 웹 개발 기초  (0) 2021.01.31
빌드하고 실행하기  (0) 2021.01.30
라이브러리 살펴보기  (0) 2021.01.30