on
[Java] JPA, MySQL연동 (Entity), JPA를 통한 CRUD
[Java] JPA, MySQL연동 (Entity), JPA를 통한 CRUD
728x90
반응형
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("[email protected]"); 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 protected], 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("[email protected]"); 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 = userRepository.findById(1L); user.ifPresent(selectUser ->{ System.out.println("user : "+ selectUser); System.out.println("email : " + selectUser.getEmail()); }); } @Test public void update(){ Optional 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 = userRepository.findById(1L); user.ifPresent(selectUser -> { userRepository.delete(selectUser); }); Optional deleteUser = userRepository.findById(1L); if(deleteUser.isPresent()){ System.out.println("지워지지 않음"); }else{ System.out.println("데이터 삭제 완료"); } } }
@Transactional
실행되더라도 실제 DB에는 반영되지 않음.
참고자료: https://life-with-coding.tistory.com/433
728x90
반응형
from http://lagooni.tistory.com/137 by ccl(A) rewrite - 2021-12-31 00:26:59