앞서 자세히 설명 했기 때문에 간단히 짚어만 보겠다.
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.2.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>2.2.224</version>
</dependency>
<?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="jakarta.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="jakarta.persistence.jdbc.user" value="sa"/>
<property name="jakarta.persistence.jdbc.password" value=""/>
<property name="jakarta.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> : DB 당 1개씩 만듦
필수 속성: DB 접근 정보임.
옵션 속성: 해당 옵션들을 true로 해두면 추후 애플리케이션을 실행하면 DB에 쿼리문이 날아갈 때 해당 쿼리문을 보여준다는 옵션들이다.
우선 위 사진을 보면 1번으로 설정 정보를 조회한다고 하여 생성한다고 되어있는데 이를 코드로 구현해주면 된다.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//code
em.close();
emf.close();
}
}
EntityManagerFactory를 만드는 순간 DB와 연결도 되고 웬만한건 다 된다.
그리고 EntityManager를 이용하여 DB에 데이터를 저장한다든지 기타 등등의 작업을 하면 된다.
create table Member (
id bigint not null,
name varchar(255),
primary key (id)
);
만약 이렇게 생긴 매우 간단한 테이블이 있다고 가정할 때
@Data
@Entity
public class Member {
@Id
private Long id;
private String name;
}
위와 같은 테이블에 매핑되는 entity가 존재해야한다.
즉, @Entity 가 붙어있어야 jpa가 처음 로딩될 때 jpa를 사용하는 애구나 라고 인식을 하고 본인이 관리하게 되는 것이다.
또한 반드시 기본생성자가 있어야한다.
왜냐하면 JPA는 기본적으로 내부에서 리플렉션 등 여러 기술을 사용하며 동적으로 객체를 생성해내야하기 때문에 반드시 기본생성자가 있어야한다.
그리고 마치 JDBC 처럼 일일이 다 쳐보자면 아래와 같다.
물런 get conn 은 없지만 대신 Transaction이 매우 중요해서 get tx 가 존재한다.
또 물론 나중엔 annotation 으로 다 퉁칠 수 있다.
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("Hello B");
em.persist(member);
Member findMember = em.find(Member.class, 2L);
findMember.setName("Hello JPA");
List<Member> result = em.createQuery("select m from Member as m", Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
System.out.println("result = " + result);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
참고로 위 코드에서 볼 수 있는 update는 굳이 persist를 해주지 않아도 되는데 그 이유는 앞서 sql의 중심 개발의 문제점을 해결하려고 마치 java collection과 같이 객체 지향적으로 편하게 개발하도록 설계되어있기 때문이다.
그래서 set 메서드를 사용하면 그냥 그대로 db에 반영되어버린다.
여기서 나온게 이제 앞서 포스팅한 순환참조의 위험이 나온다.
단순 조회, 삭제, 수정 정도는 JPA에서 기본적으로 제공하는 함수를 사용하면 되지만 조건이 붙는다든지 조금 복잡한 동적쿼리들은 처리할 수 있는 여러 방법들 중 .createQuery() 메서드로 직접 쿼리(sql아니고 jpql)를 짤 수 있기도 하다.
JPA 입장에서는 코드를 짤 때 table이 아닌 객체( entity )를 대상으로 코드를 작성한다.
그래야 앞서 sql문 중심의 설계의 한계를 벗어날 수 있고 DB들의 dialect에 영향을 받지 않기 때문이다.