인프런 김영한님 강의를 보고 정리한 글입니다
!
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gpa-basic</groupId>
<artifactId>ex1-hello-jpa</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId> // maven에 명시된 하이버네이트 라이브러리
<artifactId>hibernate-entitymanager</artifactId>
<version>5.3.10.Final</version> // spring boot 버전과 맞춰줌
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version> // 다운로드 받은 h2 데이터베이스 버전과 맞추기
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
src/main/resources
아래에 meta-inf
폴더 만든 후 persistence.xml
생성<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"> //jpa2.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"> // jpa 이름을 만드는 것 (현재는 데이터베이스가 1개)
<properties>
<!-- 필수 속성 -->
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/> // h2 콘솔(localhost:8082)에 입력했던 데이터베이스 접근 정보
<property name="javax.persistence.jdbc.password" value=""/> // h2 콘솔(localhost:8082)에 입력했던 데이터베이스 접근 정보
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/> // h2 콘솔(localhost:8082)에 입력했던 데이터베이스 접근 정보
<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>
방언
이라고 표현함벤더이름+방언
을 속성값으로 연결// h2 데이터베이스
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
// MySQL 데이터베이스 (요즘에는 이노디비를 안써도 된다고 함)
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
// Oracle 데이터베이스
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect"/>
package hellojpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class JpaMain {
public static void main(String[] args){
// EntityManagerFactory를 hello라는 unit 이름으로 생성
// 데이터베이스와 자동으로 연결
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
// code
em.close();
emf.close();
}
}
create table Member (
id bigint not null,
name varchar(255),
primary key (id)
);
@Entity
어노테이션 붙여서 Member 클래스 생성@Id
어노케이션 붙여서 pk 설정 후 id와 name 필드 만들기alt+ins
)@Entity
public class Member {
// pk
@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;
}
}
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를 hello라는 unit 이름으로 생성
// 데이터베이스와 자동으로 연결
// EntityManagerFactory는 애플리케이션 로딩 시점에 1개만 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
// 데이터베이스 커넥션되고 트랜잭션이 생성~종료될 때마다 EntityManager 하나씩 생성
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member member = new Member();
member.setId(1L);
member.setName("HelloA");
em.persist(member);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
// 엔티티매니저가 내부적으로 데이터커넥션을 물고 있으므로 사용 후 반드시 닫아줘야 함
em.close();
}
// 전체 어플리케이션이 종료되면 엔티티매니저팩토리까지 종료
emf.close();
}
}
show_sql
: 로그 출력 onformat_sql
: sql 형태로 포맷팅해서 출력use_sql_comments
: 쿼리가 왜 나왔는지 이유를 주석으로 출력Hibernate:
/* insert hellojpa.Member
*/ insert
into
Member
(name, id)
values
(?, ?)
@Table(name="USER")
으로 테이블 직접 지정 가능@Column(name="username
으로 컬럼 직접 지정 가능try {
Member findMember = em.find(Member.class, 1L);
System.out.println("findMember.id = " + findMember.getId());
System.out.println("findMember.id = " + findMember.getName());
tx.commit();
}
실행 결과
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
Member member0_
where
member0_.id=?
findMember.id = 1
findMember.id = HelloA
// 삭제
em.remove(findMember);
// 수정
findMember.setName("HelloJPA");
실행 결과
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
Member member0_
where
member0_.id=?
Hibernate:
/* update
hellojpa.Member */ update
Member
set
name=?
where
id=?
// JPQL 실습
// JPA에서는 테이블 대상으로 코드를 짜지 않음, Member 객체를 대상으로 쿼리를 함
List<Member> result = em.createQuery("select m from Member as m", Member.class).getResultList();
for (Member member : result ){
System.out.println("member.name = " + member.getName());
}
실행결과
Hibernate:
/* select
m
from
Member as m */ select
member0_.id as id1_0_,
member0_.name as name2_0_
from
Member member0_
member.name = HelloJPA
물리적인 RDB를 대상으로 쿼리를 하면 데이터베이스에 종속되므로, 엔티티를 대상으로 쿼리할 수 있는 JPQL을
JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공
- SQL 문법과 유사 (select, from, where, group by, having, join 지원)
- jpql은
엔티티 객체
를 대상으로 쿼리 -> DB dialect와 무관하게 작성 가능- sql은
데이터베이스 테이블
을 대상으로 쿼리