Super Coding Addict
어드민 페이지 만들기 (2) 본문
* 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 |