📌 프로젝트 생성
✔ 새프로젝트 생성 -> Maven 선택
- groupId : jpa-basic
- artifactId : ex1-hello-jpa
- version : 1.0.0
✔ pom.xml
에 의존성 추가
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.20.Final</version>
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
</dependency>
</dependencies>
- h2 version :
2.2.224
- hibernate version :
5.3.20.Final
- hibernate-entitymanager -> hibernate-core로 변경
javax.persistence:javax.persistence-api:2.2
에 모든 jpa 인터페이스들이 들어있음
➡ 꼭 reload 해주기!
📌 JPA 설정하기 - persistence.xml
- JPA 설정 파일
- /META-INF/persistence.xml
main/.../resources
아래에META-INF
디렉토리 생성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="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- 옵션 -->
<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>
- persistence-unit name으로 이름 지정
- javax.persistence로 시작 : JPA 표준 속성
- hibernate로 시작 : 하이버네이트 전용 속성
데이터베이스 방언
- JPA는 특정 데이터베이스에 종속 X (MySQL을 쓰다가 Oracle로 바꾸기 쉬움)
- 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다름
- 가변 문자 : MySQL은 VARCHAR, Oracle은 VARCHAR2
- 문자열을 자르는 함수 : SQL 표준은 SUBSTRING(), Oracle은 SUBSTR()
- 페이징 : MySQL은 LIMIT, Oracle은 ROWNUM
- 방언 : SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
- hibernate.dialect 속성에 지정
- H2 : org.hibernate.dialect.H2Dialect
- Oracle 10g : org.hibernate.dialect.Oracle10gDialect
- MySQL : org.hibernate.dialect.MySQL57DBDialect
- 하이버네이트는 40가지 이상의 데이터베이스 방언 지원
📌 HelloJPA 개발
- Persistence에서 시작해서 설정 정보를 조회하고 EntityManagerFactory를 생성함
- 필요할 때마다 EntityManager를 만듦
JpaMain.class
🔶 main/hellojpa/JpaMain
package hellojpa;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class JpaMain {
public static void main(String[] args){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
}
}
🔶 createEntityManagerFactory()
안에 앞에 설정파일에서 정한 persistenceUnitName
을 적어줘야 함 (xml)
➡ 실행했을 때 빨간 글씨로 ~~ 에러없이 뜨면 성공!
package hellojpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager entityManager = emf.createEntityManager();
entityManager.close();
emf.close();
}
}
- 잘 꺼지는지 확인
테이블 생성
- h2.sh를 실행하고 들어가서 Member 테이블을 생성할 것임
create table Member (
id bigint not null,
name varchar(255),
primary key(id)
);
클래스 생성
- 위에서 만든 테이블과 매핑할 객체 생성
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
(javax.persistence 사용)
🔶 필요한 Getter, Setter 생성
Member가 잘 만들어졌는지 Test
🔶 main/hellojpa/JpaMain.class
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();
Member member = new Member();
member.setId(2L);
member.setName("HelloB");
em.persist(member);
tx.commit();
em.close();
emf.close();
}
}
🔶 EntityManagerFactory
는 애플리케이션 로딩 시점에 딱 한번 만들어야 함
- 어떤 상황이 생길 때마다 EntityManager를 만들어서 사용
🔶 member
를 하나 만들어서 em.persist()
를 이용해 저장해줌
member.setId()
,member.setName()
을 이용해서 값 넣어줘야 함
❗JPA에서는 트랜잭션이라는 단위가 매우 중요함
모든 데이터를 변경하는 등의 작업은 트랜잭션 안에서 해야함
🔶 em.getTransaction();
을 이용해서 호출해서 트랜잭션 생성
tx.begin()
으로 시작tx.commit()
하면 쿼리가 날라감
- 설정에서 hibernate.show_sql을 true로 해놨기 때문에 쿼리가 보임
hibernate.use_sql_comments
를 true로 해놨기 때문에 설명도 해줌
DB에 저장되었는지 확인!
- h2에 가서 SELECT * FROM MEMBER; 실행해보면 저장된걸 확인할 수 있음
Table(name="USER")
- USER 테이블에 매핑
@Column(name = "username`)
- db에서 username과 매핑됨
트랜잭션에서 롤백
try {
Member member = new Member();
member.setId(2L);
member.setName("HelloB");
em.persist(member);
tx.commit();
}catch (Exception e){
tx.rollback();
}
finally {
em.close();
}
- 정상적일땐 커밋을 하고 문제가 생기면 rollback
회원 수정하기
try {
Member findMember = em.find(Member.class, 1L);
findMember.setName("UpdateMemberName");
tx.commit();
}catch (Exception e){
tx.rollback();
}
finally {
em.close();
}
🔶 em.find(Member.class, 1L);
entityManager
에 있는 find 사용- 찾고자하는 Member Id값(Pk) 입력
🔶 수정한 후에 em.persist(findMember)
로 저장하지 않아도 알아서 저장됨
- 수정이 됐는지 감지하고 바꼈으면 update 쿼리를 날리고 commit함
회원 삭제
try {
Member findMember = em.find(Member.class, 1L);
em.remove(findMember);
tx.commit();
}catch (Exception e){
tx.rollback();
}
finally {
em.close();
}
주의❗
- 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유
- 엔티티 매니저는 쓰레드간에 공유 X (사용하고 버려야 함)
- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행
📌 JPQL 소개
- 가장 단순한 조회 방법
- EntityManager.find()
- 객체 그래프 탐색(a.getB().getC())
- 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
❓ 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
➡ JPQL로 전체 회원 검색
- JPQL로 ID가 2 이상인 회원만 검색
- JPQL로 이름이 같은 회원만 검색
- JPQL에 대해 자세한 내용은 객체지향 쿼리에서 학습
List<Member> result = em.createQuery("SELECT m from Member as m", Member.class).getResultList();
for(Member member:result){
System.out.println("member.getName() = " + member.getName());
}
- 쿼리가 sql과 약간 다름!
List<Member> result = em.createQuery("SELECT m from Member as m", Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
- 1~10번 가져오라는 뜻
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- ❗ 문제는 검색 쿼리
- 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
- 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
- JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
- SQL과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
- JPQL은 엔티티 객체를 대상으로 쿼리
- SQL은 데이터베이스 테이블을 대상으로 쿼리
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
- SQL을 추상화해서 특정 데이터베이스 SQL에 의존 X
- JPQL을 한마디로 정의하면 객체 지향 SQL
<자바 ORM 표준 JPA 프로그래밍 - 기본편_김영한>을 수강하고 작성한 글입니다

PREV
[자바 ORM 표준 JPA 프로그래밍 - 기본편]1. JPA 소개
❗ 지금은 객체를 관계형 DB에 관리하는 시대 ➡ SQL 사용 📌 SQL이란? Structured Query Language 데이터베이스 시스템에서 자료를 처리하는 용도로 사용되는 구조적 데이터 질의 언어(에스큐엘, 시퀄이
nyeroni.tistory.com
NEXT
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 3. 영속성 관리 - 내부 동작 방식
❗ JPA에서 가장 중요한 2가지 객체와 관계형 데이터 베이스 매핑하기 (ORM, Object Relational Mapping) 영속성 컨텍스트 📌 영속성 컨텍스트 ⚡ 영속성 컨텍스트란 JPA를 이해하는데 가장 중요한 용어 "
nyeroni.tistory.com
'인프런 Spring 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 - 기본편' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍 - 기본편]6. 다양한 연관관계 매핑 (0) | 2024.01.23 |
---|---|
[자바 ORM 표준 JPA 프로그래밍 - 기본편]5. 연관관계 매핑 기초 (0) | 2024.01.23 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 4. 엔티티 매핑 (0) | 2024.01.23 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 3. 영속성 관리 - 내부 동작 방식 (0) | 2024.01.23 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편]1. JPA 소개 (0) | 2024.01.23 |