JPA 개발 들어가기
2021. 2. 19. 21:10ㆍSpring/JPA
JPA 들어가기
라이브러리 추가 - pom.xml
Spring Boot에서는 자동으로 다 해준다! 하지만 지금 프로젝트에서는 한땀한땀 다 해보는게 중점이어서 xml파일도 작성해보는거기 때문에 이점을 주의하자!!
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
</dependencies>
이렇게 JPA 관련 라이브러리와 H2데이터 베이스 라이브러리를 넣어준다.
여기서 javax.xml.bind 라는 라이브러리는 jdk11버전으로 프로젝트를 실행시 일어나는 Java EE 모듈과 CORBA 모듈이 Deprecated되면서 기본 참조가 되지 않아 발생한 문제였다.(출처: https://luvstudy.tistory.com/61 [파란하늘의 지식창고]) - 이러한 오류는 위와 같이 라이브러리를 추가하면 해결할 수 있다.
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/~/basic-jpa"/>
<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"/>
</properties>
</persistence-unit>
</persistence>
- 이 파일은 JPA가 우리가 선택한 DB(나는 h2 DB)를 관리하기 위한 속성 파일(?) 이라고 생각하면 된다.
persistence-unit name="hello"
이 부분은 JPA가 DB를 관리하는 문지기(?) 같은 이름이라고 보면 된다. 이 후에 코드에서 hello를 사용한는 코드에서 조금 더 자세히 다루겠다.- JPA는 DB에 종속적이지 않게 설계를 하였는데 그 부분이 바로
org.hibernate.dialect.H2Dialect
여기다. 만약 MySQL, Oracle을 사용하고 싶으면org.hibernate.dialect.Oracle10gDialect
,org.hibernate.dialect.MySQL5InnoDBDialect
같은 속성을 사용하면된다. 그래서 나중에 DB를 교체하는 일이 생기면 이 부분을 건드리면 되겠다.!!
JPA 구동 방식
객체와 테이블을 생성하고 맵핑하기
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 : 데이터베이스 PK와 매핑
회원 CRUD
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();
}
// **데이터 수정**
try {
Member findMember = em.find(Member.class, 1L);
System.out.println("========수정 전========");
System.out.println("findMemberId = " + findMember.getId());
System.out.println("findMember.getName() = " + findMember.getName());
findMember.setName("HelloB");
// 여기서 persist를 안해도된다!!
tx.commit();
System.out.println("========수정 후========");
System.out.println("findMemberId = " + findMember.getId());
System.out.println("findMember.getName() = " + findMember.getName());
}catch (Exception e) {
tx.rollback();
}finally {
em.close();
}
// **데이터 삭제**
try {
Member findMember = em.find(Member.class, 1L);
em.remove(findMember);
tx.commit();
}catch (Exception e) {
tx.rollback();
}finally {
em.close();
}
// **JPQL로 모든 멤버 가져오기**
try{
List<Member> findMembers = em.createQuery("select m from Member as m", Member.class)
.getResultList();
for (Member member : findMembers) {
System.out.println("member.getName() = " + member.getName());
}
tx.commit();
}catch (Exception e) {
tx.rollback();
}finally {
em.close();
}
emf.close();
EntityManagerFactory
- DB당 하나만 생성된다.
EntityManager
- 쓰레드간에 공유 X(사용하고 버려야한다.) 예) 하나의 고객이 사용하고 버린다. 다른 고객이 사용하지 않는다.
주의!! JPA의 데이터 변경은 트랜잭션 안에서 실행
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
- 위에서 언급했지만
persistence.xml
에서persistence-unit name="hello"
를 여기서 사용하는 것이다.
수정부분에서 persist를 안해도 되는 이유!!!
- JPA에서 모든 객체를 감시하고 있다. 그래서 만약 setName메서드를 통해서 이름을 바꾸면 JPA가 감지를 하여 자동적으로 커밋에서 바꿔준다.
JPQL로 검색하기
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- 문제는 검색 쿼리
- 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
- 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
결론 : JPQL은 엔티티 객체를 대상으로 쿼리
SQL은 데이터베이스 테이블을 대상으로 쿼리
사진은 김영환님의 JPA기본편을 참고하였습니다.(인프런)
'Spring > JPA' 카테고리의 다른 글
Spring JPA [상속관계 맵핑] (0) | 2021.06.17 |
---|---|
[Spring JPA] 다양한 연관관계 매핑 (0) | 2021.04.19 |
Spring JPA 영속성 컨텍스트 (0) | 2021.02.28 |
Spring JPA 엔티티 맵핑 (0) | 2021.02.27 |
JPA는 왜 사용하는가? (0) | 2021.02.19 |