프로젝트 세팅
<?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="oracle.jdbc.driver.OracleDriver" />
<property name="javax.persistence.jdbc.user" value="springjpa" />
<property name="javax.persistence.jdbc.password" value="springjpa" />
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL10Dialect" /> -->
<!-- 테이블 생성 옵션 -->
<property name="hibernate.hbm2ddl.auto" value="create"/>
<!-- 옵션 -->
<!-- 콘솔에 하이버네이트가 실행하는 SQL문 출력 -->
<property name="hibernate.show_sql" value="true" />
<!-- SQL 출력 시 보기 쉽게 정렬 -->
<property name="hibernate.format_sql" value="true" />
<!-- 쿼리 출력 시 주석(comments)도 함께 출력 -->
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
</persistence>
이론
- JPQL ( Java Persistence Query Language )
- JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
- JPQL은 엔티티 객체를 대상으로 쿼리 작성
- SQL을 추상화해서 특정 데이트베이스에 의존하지 않게 된다.
- JPA는 JPQL을 분석 후, 적절한 SQL을 만들어 데이터베이스를 조회
- 규칙
- 엔티티 이름
-> 테이블명 대신 엔티티명을 사용, @Entity(name ="" ) 으로 설정 가능
-> 지정하지 않을 시 클래스 명을 기본값으로 사용 ( 추천 )
- 별칭은 필수
-> JPQL은 별칭이 필수이다.
-> AS는 생략이 가능하다
- TypedQuery, Query
- TypedQuery : 반환 타입이 명확할 때 사용
TypedQuery<Member> query = ( " select m from member m" , Member.class )
TypedQuery<String> query = ( " select m.username from member m" , String.class )
- Query : 반환 타입이 명확하지 않을 때 사용
Query query = ( " select m.username from member m")
- 결과 조회 API
1. query.getResultList()
: 결과가 없으면 빈 리스트 반환
: 빈 collection이 반환되기 때문에 nullPointException에 대한 걱정은 안해도 된다.
2. query.getSingleResult()
: 결과가 정확히 하나 ( 주의 ) , 단일 객체 반환
: 결과가 없을 경우 -> NoResultException
: 결과가 둘 이상이면 -> NonUniqueResultException
- 파라미터 바인딩
- 이름기준
select m from Member m where m.username = :username
query.setParameter('username', usernameParam);- 위치기준 ( 권장하지 않음 )
select m from Member m where m.username = ?1
query.setParameter(1, usernameParam);
JpaMain.java
생성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 {
List<Member> result = em.createQuery(
"select m from Member m where m.username like '%kim%'", // 이때 쿼리문의 Member 는 자바클래스명
Member.class).getResultList();
for( Member member : result) {
System.out.println("member = " + member);
}
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
emf.close();
}
}
}
JpaMain.java
수정...
// TypedQuery
// 타입 정보가 Member로 명확할때
TypedQuery<Member> query =
em.createQuery("select m from Member m", Member.class);
// 타입 정보가 String.class로 반환이 명확 할 때
TypedQuery<String> query2 =
em.createQuery("select m.username from Member m", String.class);
// m.username ( String ), m.age ( int ) : 반환타입이 명확하지 않을 때 ( 한가지가 아닐 때 )
Query query3 =
em.createQuery("select m.username, m.age from Member m");
tx.commit();
...
JpaMain.java
수정...
// getResultList()
TypedQuery<Member> query4 =
em.createQuery("select m from Member m", Member.class);
List<Member> resultList = query4.getResultList();
// 결과값 하나일 때, getSingleResult()
TypedQuery<Member> query5 =
em.createQuery("select m from Member m where m.id = 10", Member.class);
Member result2 = query5.getSingleResult();
tx.commit();
...
Member.java
수정...
@Column(name = "name", nullable = false)
private String username;
private int age;
...
JpaMain.java
수정...
try {
Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);
// 파라미터 바인딩 - 이름 기준
TypedQuery<Member> query =
em.createQuery("select m from Member m where m.username = :username", Member.class);
query.setParameter("username", "member1");
Member result = query.getSingleResult();
System.out.println("result : " + result.getUsername());
tx.commit();
...
JpaMain.java
수정...
try {
Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);
Member result =
em.createQuery("select m from Member m where m.username = ?1", Member.class)
.setParameter(1, "member1")
.getSingleResult();
System.out.println("result : " + result.getUsername());
tx.commit();
} catch (Exception e) {
...