java 스프링부트 ( spring boot ) / JPQL

김동명·2022년 12월 9일
0

스프링부트

목록 보기
17/19

프로젝트 세팅

  • 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="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

  • 파라미터 바인딩
    1. 이름기준
      select m from Member m where m.username = :username
      query.setParameter('username', usernameParam);
    2. 위치기준 ( 권장하지 않음 )
      select m from Member m where m.username = ?1
      query.setParameter(1, usernameParam);



1. 기본

  • 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();
		}
		
	}
	
}

  • 결과




2. TypedQuery

  • 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();
...



3. 결과 조회 API

  • 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();
...



4. 파라미터 바인딩

  • Member.java 수정
    • age 추가
...
	@Column(name = "name", nullable = false)
	private String username;
	
	private int age;
...

4-1. 이름 기반

  • 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();
...

  • 결과



4-2. 위치기반 - 권장하지 않음

  • 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) {
...
  • 결과
profile
코딩공부

0개의 댓글