본문 바로가기
개인 공부/JPA

02 JPA 시작

by hanyugyeong 2023. 9. 19.
반응형
SMALL

2.3.1  메이븐과 사용 라이브러리 관리 

<?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>org.example</groupId>
    <artifactId>ex1-hello-jpa</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- JPA 하이버네이트 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.3.10.Final</version>
        </dependency>
        <!-- H2 데이터베이스 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>
</project>

2.4 객체 매핑 시작 

@Entity
@Table(name="MEMBER")
public class Member {
	@Id
	@Column(name="ID")
	private String id; //아이디
	@Column(name="NAME")
	private String username; //이름
	private Integer age; //나이

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}
}

* @Entity

이 클래스를 테이블과 매핑한다고 JPA에게 알려준다. 이렇게 @Entity가 사용된 클래스를 엔티티 클래스라 한다. 

* @Table 

엔티티 클래스에 매핑할 테이블 정보를 알려준다.여기서는 name 속성을 사용해서 Member 엔티티를 MEMBER 테이블에 매핑했다. 

* @Id

엔티티 클래스의 필드를 테이블의 기본 키(Primary key)에 매핑한다. 

* @Column

필드를 칼럼에 매핑한다. 

* 매핑 정보가 없는 필드 

age 필드에는 매핑 어노테이션이 없다. 

2.5 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/~/test;MODE=MySQL"/>
            <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.jdbc.batch_size" value="10"/>
            <property name="hibernate.hbm2ddl.auto" value="create" />
           </properties>
       </persistence-unit>
   </persistence>

2.6  애플리케이션 개발 

객체 매핑을 완료하고 persistence.xml로 JPA 설정도 완료했다. 

public class JpaMain {
    public static void main(String[] args) {
        //db당 하나만 생성
        //[엔티티 메니저 팩토리] - 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        //[엔티티 메니저] - 생성 
        EntityManager em = emf.createEntityManager();
        //[트랜잭션] - 획득
        EntityTransaction tx = em.getTransaction();
        //CODE
        try{
            tx.begin(); //[트랜잭션] -시작 
            logic(em); //비즈니스 로직 실행
            em.clear(); //[트랜잭션] - 커밋 

            tx.commit();   //[트랜잭션] - 커밋 
        }catch (Exception e){
            tx.rollback(); //[트랜잭션] - 롤백
        }finally {
            em.close(); //[엔티티 메니저] - 종료
        }
        emf.close(); // [엔티티 메니저 팩토리] - 종료
    }
    //비즈니스 로직 
    private static void logic(EntityManager em){
        
    }
    
}

코드는 크게 3부분으로 나뉘어 있다. 

* 엔티티 메니저 설정 

* 트랜잭션 관리 

* 비즈니스 로직 

2.6.1 엔티티 메니저 설정 

엔티티 메니저의 생성 과정을 분석해보자 

* 엔티티 메니저 팩토리 생성 

-> Pesistence 클래스를 사용하는데 이 클래스는 엔티티 메니저 팩토리를 생성해서 JPA를 사용할 수 있게 준비한다. 

 EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

엔티티 메니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다. 

* 엔티티 메니저 생성 

 //[엔티티 메니저] - 생성 
EntityManager em = emf.createEntityManager();

엔티티 메니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다. 

참고로 엔티티 메니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드간에 공유하거나 재사용하면 안 된다. 

2.6.2 트랜잭션 관리 

JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다. 트랜잭션을 시작하려면 엔티티 메니저(em)에서 트랜잭션 API를 받아와야 한다. 

//[트랜잭션] - 획득
        EntityTransaction tx = em.getTransaction();
        //CODE
        try{
            tx.begin(); //[트랜잭션] -시작
            logic(em); //비즈니스 로직 실행
            em.clear(); //[트랜잭션] - 커밋

            tx.commit();   //[트랜잭션] - 커밋 
        }catch (Exception e){
            tx.rollback(); //[트랜잭션] - 롤백
        }

2.6.3 비즈니스 로직 

비즈니스 로직은 단순하다. 회원 엔티티를 하나 생성한 다음 엔티티 메니저를 통해 데이터베이스에 등록,수정,삭제,조회한다. 

//비즈니스 로직
    private static void logic(EntityManager em){
        String id = "id1";
        Member member = new Member();
        member.setId(id);
        member.setUsername("지한");
        member.setAge(2);

        //등록
        em.persist(member);

        //수정
        member.setAge(20);

        //한 건 조회
        Member findMember = em.find(Member.class,id);
        System.out.println("findMember ="+findMember.getUsername()+", age="+findMember.getAge());

        //목록 조회
        List<Member> members = em.createQuery("select m from Member m",Member.class).getResultList();
        System.out.println("members.size = "+members.size());

        //삭제
        em.remove(member);
    }

* 등록 

String id = "id1";
Member member = new Member();
member.setId(id);
member.setUsername("지한");
member.setAge(2);

//등록
em.persist(member);

엔티티를 저장하려면 엔티티 메니저의 persist() 메소드에 저장할 엔티티를 넘겨주면 된다. JPA는 회원 엔티티의 매핑 정보를 분석해서 다음과 같은 SQL을 만들어 데이터베이스에 전달한다. 

INSERT INTO MEMBER (ID, NAME, AGE) VALUES ('id1', '지한', 2);

* 수정 

//수정
member.setAge(20);

* 삭제 

//삭제
em.remove(member);

* 한 건 조회 

 //한 건 조회
Member findMember = em.find(Member.class,id);

2.6.4 JPQL

하나 이상의 회원 목록을 조회하는 다음 코드를 자세히 살펴보자 

//목록 조회
List<Member> members = em.createQuery("select m from Member m",Member.class).getResultList();
System.out.println("members.size = "+members.size());

JPA는 엔티티 객체를 중심으로 개발을 하므로 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색해야 한다. 

 

JPA는 SQL을 추상화한 JPQL이라는 객체지향 쿼리 언어를 제공한다. JPQL은 SQL과 문법이 거의 유사하다. 

둘의 가장 큰 차이점은 다음과 같다

* JPQL은 엔티티 객체를 대상으로 쿼리한다. 쉽게 이야기해서 클래스와 필드를 대상으로 쿼리한다. 

* SQL은 데이터베이스 테이블을 대상으로 쿼리한다. 

 

반응형
LIST

'개인 공부 > JPA' 카테고리의 다른 글

05 연관관계 매핑 기초  (0) 2023.10.04
04 엔티티 매핑  (0) 2023.09.20
03 영속성 관리  (0) 2023.09.19
08 프록시와 연관관계 관리  (0) 2023.08.03
실전 예제 4. 상속 관계 매핑  (0) 2023.08.02