Hello JPA - 프로젝트 생성
강의와 다르게 진행한 점
DB 사용을 H2가 아닌 MySQL 사용
pom.xml 설정
dependency에 사용할 라이브러리를 적는다.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ex1-hello-jpa</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Archetype - ex1-hello-jpa</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.3.10.Final</version>
</dependency>
<!-- 데이터베이스 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
</project>
라이브러리 버전 선택하는 방법
아래 페이지에서 내가 선택한 스프링 부트 버전의 Reference Docs > Dependency Versions를 확인한다.
https://spring.io/projects/spring-boot#learn
org.hibernate이 어떤 버전으로 맞춰져 있는지 확인한다. 아래에서는 6.4.4 버전임을 알 수 있다.
MySQL은 내 connector 버전과 동일하게 설정하였다.
JPA 설정하기
꼭 resources > META-INF 아래에 persistence.xml 파일로 설정한다.
src/main/resources/META-INF/maven/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="hello">
<properties>
<!-- 필수 속성 -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="사용자명"/>
<property name="javax.persistence.jdbc.password" value="비밀번호"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/데이터베이스명?useSSL=false&serverTimezone=UTC"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<!-- 옵션 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
</properties>
</persistence-unit>
</persistence>
hibernate.dialect 데이터베이스 방언
JPA는 특정 DB에 종속적이지 않게 설계되었다. DB는 각각 제공하는 SQL 문법과 함수가 조금씩 다른데 이를 JPA 입장에서는 방언이라고 이야기 한다. 즉 SQL 표준을 지키지 않는 특정 DB만의 고유한 기능을 방언이라고 한다. 이 방언은 hibernate.dialect 속성에 지정하여 사용할 수 있다.
Hello JPA - 애플리케이션 개발
JPA 구동 방식
1. JPA는 Persistence 라는 클래스를 가지고 있다.
2. 이 클래스에서 psersistence.xml에 설정한 설정 정보를 읽어 EntityManagerFactory라는 클래스를 생성한다.
3. EntityManagerFactory에서 EntityManager을 생성하여 실행시킨다.
JPA 구동 실습
① \src\main\java\hellojpa\JpaMain.java 파일을 생성하여 Persistence 클래스의 createEntityManagerFactory 함수를 아래와 같이 불러온다. 이때 persistenceUnitName은 persistence.xml에 설정한 이름과 같아야 한다.
이 EntityManagerFactory를 생성하는 순간 DB와의 연결 등이 자동으로 이루어진다. 이후 애플리케이션이 모두 완료되면 EntityManagerFactory까지 close 해주어야 한다.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//실제 코드 작성
em.close();
emf.close();
}
}
② MySQL에 접속하여 member 테이블을 생성한다.
use jpa_study;
create table Member (
id bigint not null,
name varchar(255),
primary key (id)
);
③ SpringBoot 프로젝트에서 객체와 테이블을 생성하고 매핑한다.
src/main/java/hellojpa/Member.java 파일을 생성하여 아래와 같이 코드를 작성한다.
package hellojpa;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Member {
@Id
private Long id;
private String name;
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity : JPA가 자신이 관리해야 할 객체로 인식하도록 해준다.
@Id : DB의 Primary Key와 매핑되도록 해준다.
④ JpaMain.java에 Member 저장 코드를 작성한다.
Member를 저장하는 등의 한 동작 단위마다 EntityManager을 생성하고 종료해주어야 한다. JPA에서는 모든 작업이 트랜잭션 안에서 이루어져야 한다. 따라서 Transaction을 생성하고 종료해야 한다.
package hellojpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member member = new Member();
member.setId(2L);
member.setName("HelloB");
em.persist(member);
tx.commit();
} catch (Exception e){
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
DB에서 SELECT 문으로 저장한 Member 정보를 조회해볼 수 있다.
이렇게 쿼리를 한 줄도 작성하지 않아도 JPA가 매핑 정보를 파악하여 쿼리를 대신 작성하여 작동해준다.
Member 수정은 set 메소드를 사용하여 따로 저장하지 않아도 가능하며, Member 삭제는 remove 메소드를 사용하여 가능하다. Member 조회는 find 메소드를 사용하여 Member을 찾아 출력하면 된다.
특히 Member 수정에서는 Java 객체의 값만 바꾸었는데 DB까지 수정되는 것을 확인할 수 있는데 이는 JPA는 이 Member을 관리하는데 트랜잭션을 커밋하는 시점에 JPA가 변동된 사항이 있는지 체크하고 변동된 사항이 있다면 UPDATE 쿼리를 실행하기 때문에 가능한 것이다.
정리
여기서 EntityManagerFactory는 하나만 생성하여 어플리케이션 전체에서 공유한다. EntityManagerFactory의 EntityManager은 요청이 올 때마다 사용하고 버리고를 반복한다. 따라서 EntityManager은 Thread 간 공유를 하면 안된다. 또한 JPA의 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다.
JPQL 소개
JPA를 사용하면 객체를 중심으로 개발하게 되는데 검색 쿼리 실행할 때에도 객체를 대상으로 검색하게 된다. 그러나 모든 DB 데이터를 객체로 변환하여 검색하는 것은 불가능하다. 따라서 어플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하며 따라서 JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다. SQL 문법과 유사하지만 JPQL은 엔티티 객체를 대상으로 쿼리를 날리며 SQL은 데이터베이스 테이블을 대상으로 쿼리를 날린다는 차이점이 있다. JPQL로는 전체 회원 검색, ID가 2인 회원 검색, 이름이 같은 회원 검색 등이 가능하다. JPQL은 SQL을 추상화 한 것이기 때문에 특정 DB SQL에 의존적이지 않다는 특징과 데이터 페이징이 가능하다는 장점이 있다.
'Spring > SpringBoot&JPA' 카테고리의 다른 글
[JPA] 엔티티 매핑 (매핑 어노테이션, DDL, 기본키 전략) (0) | 2024.03.22 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] 섹션3. 영속성 관리 - 내부 동작 방식 (0) | 2024.03.18 |
[자바 ORM 표준 JPA 프로그래밍] 섹션1. JPA 소개 (0) | 2024.03.15 |
[스프링부트와 JPA 활용 2] Section2. API 개발 고급 - 준비 (0) | 2023.11.27 |
[스프링부트와 JPA 활용 2] Section1 중 "회원 삭제 API" (0) | 2023.11.22 |