본문 바로가기
공부/자바 (Java)

[Java] JPA, MySQL연동 (Entity), JPA를 통한 CRUD

by Lagooni 2021. 12. 31.

JPA (Java Persistence API)?

ORM(Object Relational Mapping)으로 인터페이스의 모음이다.

RDB 데이터베이스의 정보를 객체지향으로 손쉽게 활용할 수 있도록 도와주는 도구이다.

Object(객체)와 Relation(관계형 DB) 둘 간의 맵핑을 통해서 보다 손쉽게 적용할 수 있는 기술을 제공해준다.

또한 쿼리에 집중하기 보다는 객체에 집중함으로써, 조금 더 프로그래밍 적으로 많이 활용할 수 있다.


MySQL연동하기

mysql.server start

study 스키마

의존성 추가 jpa, mysql

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('mysql:mysql-connector-java')
    compileOnly 'org.projectlombok:lombok:1.18.10'
    annotationProcessor 'org.projectlombok:lombok:1.18.10'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

resources - application.properties 혹은 application.yaml파일

스프링부트가 애플리케이션을 구동할 때 자동으로 로딩하는 파일이다.

본인의 username과 패스워드를 적는다.

# db source url
spring.datasource.url=jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true

# db response name
spring.datasource.username=root

# db response password
spring.datasource.password=패스워드

// Hibernate: insert into user (account, created_at. ...) 로그 표시
spring.jpa.show-sql=true

Entity

Camel Case: 단어표기시 첫문자는 소문자로 시작하며 띄어쓰기 대신 대문자로 단어를 구분한다. Java의 변수를 선언할 때 사용 (phoneNumber)

Snake Case: 단어표기시 모두 소문자로 표기하며 띄어쓰기 대신( _ ) 로 표기한다. DB컬럼에 사용된다. (phone_number)

API통신 규격에에는 Snake Case를 많이 사용한다.

JPA에서의 Entity: 테이블을 자동으로 생성해주는 기능 존재

DB Table == JPA Entity

컬럼, 테이블명이 DB의 이름과 동일하다면 명시해주지 않아도 됨.

package com.example.admin_study.model.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@Entity
public class User {

    public User() {

    }
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String account;
    private String email;
    private String phoneNumber;
    private LocalDateTime createdAt;
    private String createdBy;
    private LocalDateTime updatedAt;
    private String updatedBy;

}

@Repository

따로 쿼리문을 작성하지 않아도 기본적인 CRUD가 가능하다.

JpaRepository<앤티티 객체, PK의 타입> 상속


@Autowired 

스프링에서 빈 인스턴스가 생성된 이후 @Autowired를 설정한 메서드가 자동으로 호출되고, 인스턴스가 자동으로 주입됩니다. 
스프링의 핵심 기능중 하나인 DI (Dependency Injection; 의존관계 주입)는 객체를 직접 생성하는것이 아닌 외부에서 생성하여 주입시켜 주는 방식이다.

 

Create: 테스트에서 유저정보를 mysql에 넣어보자

package com.example.admin_study.repository;

import com.example.admin_study.AdminStudyApplicationTests;
import com.example.admin_study.model.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;

public class UserRepositoryTest extends AdminStudyApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void create(){
        User user = new User();
        user.setAccount("TestUser01");
        user.setEmail("TestUser01@gmail.com");
        user.setPhoneNumber("010-1111-1111");
        user.setCreatedAt(LocalDateTime.now());
        user.setCreatedBy("admin");

        User newUser = userRepository.save(user);
        System.out.println("newUser : " +newUser);
    }
}
// 결과
Hibernate: insert into user (account, created_at, created_by, email, phone_number, updated_at, updated_by) values (?, ?, ?, ?, ?, ?, ?)
newUser : User(id=2, account=TestUser01, email=TestUser01@gmail.com, phoneNumber=010-1111-1111, createdAt=2021-12-30T21:43:43.002008, createdBy=admin, updatedAt=null, updatedBy=null)

읽기, 업데이트, 삭제

더보기
package com.example.admin_study.repository;

import com.example.admin_study.AdminStudyApplicationTests;
import com.example.admin_study.model.entity.User;
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 java.time.LocalDateTime;
import java.util.Optional;

public class UserRepositoryTest extends AdminStudyApplicationTests {

    @Autowired
    private UserRepository userRepository;

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

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

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

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

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

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

            userRepository.save(selectUser);
        });
    }

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

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

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

        if(deleteUser.isPresent()){
            System.out.println("지워지지 않음");
        }else{
            System.out.println("데이터 삭제 완료");
        }
    }
}

@Transactional

실행되더라도 실제 DB에는 반영되지 않음.

 

참고자료: https://life-with-coding.tistory.com/433

 

[Spring] @Autowired 와 DI 개념 정리

인트로 안녕하세요 :) 오늘은 Spring 프레임워크의 @Autowird 어노테이션, 이를 설명하기 위한 DI개념에 대해 정리하겠습니다. 목차 1) DI(Dependency Injection) 개념 2) @Autowired 개념 3) @Autowired 와 @Re..

life-with-coding.tistory.com

 

댓글