본문 바로가기
Programming/Spring

JPA 스프링 연동

by TinKerBellBass 2017. 8. 14.
728x90
반응형
참고 도서
스프링 퀵 스타트
국내도서
저자 : 채규태
출판 : 루비페이퍼 2016.06.30
상세보기


1. JPA 사용 준비

① 프로젝트를 마우스 우클릭해서 properties 창을 열고, 
    Project Facets 에서 JPA 항목 체크
    -> src/main/java/META-INF 폴더에 persistence.xml 파일 생성됨

Maven Repository에서 hibernate entity manager, spring orm 를 검색하여 설정


2. JPA 의 Dialect 클래스

ORM 프레임워크는 SQL을 자동으로 생성하는데, 데이터베이스의 종류에 따라 조금씩 쿼리문에 차이가 있다.

그래서 JPA에는 특정 데이터베이스에 최적화된 쿼리를 제공하기 위해 데이터베이스마다 다른 Dialect 클래스가 만들어져 있다.

Dialect의 사전적 의미는 사투리, 방언으로 각각의 데이터베이스마다 가지는 사투리를 정의하고 있다는 것을 의미한다.


hibernate-core jar 파일을 까서 org.hibernate.dialect 패키지를 열어보면

수 많은 데이터베이스 Dialect가 클래스로 정의되어 있다. 

 데이터베이스

Dialect Class 

 MySQL

 org.hibernate.dialect.MYSQLDialect 

 Oracle(any version)

 org.hibernate.dialect.OracleDialect

 Oracle 9i/10g

 org.hibernate.dialect.Oracle9Dialect

 H2

 org.hibernate.dialect.H2Dialect

 Microsoft SQL Server 

 org.hibernate.dialect.SQLServerDialect

 PostgreSQL 

 org.hibernate.dialect.PostgreDialect

 DB2 

 org.hibernate.dialect.DB2Dialect

 Sybase 

 org.hibernate.dialect.SybaseDialect

 SAP DB

 org.hibernate.dialect.SAPDBDialect


3. JPA 설정파일(persistence.xml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!-- 
영속성 유닛 이름, 영속성 컨텍스트를 관리하는 EntityManager 객체를 생성하는
EntityManagerFactory 객체를 생성하기 위한 설정에 사용할 영속성 유닛 이름
 -->
<persistence-unit name="springBoard">
<!-- Entity Class 등록 -->
    <class>com.neverland.JPA.board.BoardVO</class>
    <properties>
    <!-- 필수 속성, 사용할 데이터베이스에 맞는 사투리(SQL) 설정 -->
        <property name="hibernate.dialect" value="사용할 DB의 dialect"/>
 
    <!-- 옵션 속성, true면 작동, false면 작동 안함 -->
        <!-- 생성된 SQL을 콘솔에 출력 -->
        <property name="hibernate.show_sql" value="true"/>
 
        <!-- SQL을 출력할 때, 일정한 포맷으로 보기 좋게 출력 -->
        <property name="hibernate.format_sql" value="true"/>
 
        <!-- SQL에 포함된 주석도 같이 출력 -->
        <property name="hibernate.use_sql_comments" value="false"/>
 
        <!-- 새로운 키 생성 전략을 사용 -->
        <property name="hibernate.id.new_generator_mappings" value="true"/>
 
        <!--
        테이블 생성, 수정, 삭제 등 DDL SQL을 자동으로 처리
        
        value 속성 값
          create 
            기존 테이블을 삭제하고 엔티티 클래스의 매핑 설정을 참고하여 새 테이블 생성(DROP - CREATE)
          create-drop
            create와 같지만, 어플리케이션 종료 직전에 생성한 테이블을 삭제(DROP - CREATE - DROP)
           update
            사용 중인 테이블이 있으면 새 테이블을 생성하지 않고 재사용, 
            엔티티 클래스의 매핑 설정이 변경되면 변경된 내용만 반영(ALTER)
        -->
        <property name="hibernate.hbm2ddl.auto" value="create"/>
 
    <!-- DB 연동은 스프링에서, JPA 에서 DB 연동 할 경우 -->
    <!--
        <property name="javax.persistence.jdbc.driver" value="사용할 DB의 드라이버"/>
        <property name="javax.persistence.jdbc.user" value="사용할 DB의 유저이름"/>
        <property name="javax.persistence.jdbc.password" value="사용할 DB의 패스워드"/>
        <property name="javax.persistence.jdbc.url" value="사용할 DB의 url"/>
    -->
    </properties>
<persistence-unit> 
cs


4. Spring 과 연동

비지니스 컴포넌트를 위한 스프링 설정 파일인 applicationContext.xml 에 JPA 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!-- JPA 인터페이스를 구현하고 있는 ORM 프레임워크 중 사용할 것을 선택 -->
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
 
<!-- 
영속성 컨텍스트를 관리하는 EntityManager 객체를 생성하는
EntityManagerFactory 클래스를 bean 등록
 
LocalContainerEntityManagerFactoryBean 클래스, AbstractEntityManagerFactoryBean 을 상속하고 있다
public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean
        implements ResourceLoaderAware, LoadTimeWeaverAware {}
 
AbstractEntityManagerFactoryBean 클래스, FactoryBean<EntityManagerFactory> 를 구현하고 있다
public abstract class AbstractEntityManagerFactoryBean implements
        FactoryBean<EntityManagerFactory>, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware,
        InitializingBean, DisposableBean, EntityManagerFactoryInfo, PersistenceExceptionTranslator, Serializable {
 
DAO 에서 사용할 때는, @PersistenceContext 어노테이션을 사용
@PersistenceContext 는 EntityManagerFactory 를 통해 EntityManager 객체를 생성시켜서 주입
 
@Repository
public class BoardDAOJPA{
    @PersistenceContext
    private EntityManager em;
}
-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <!-- DataSouce, JPA Vendor Adapter 를 속성으로 주입 -->
    <property name="dataSource" ref="dataSource"></property>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
</bean>
 
<!-- Transaction 설정 -->
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <!-- EntityManagerFactory 로부터 EntityManager 객체를 받아서 주입 -->
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
 
 
<!--
Java 소스로 EntityManagerFactory 를 설정하는 방법
 
JPA 설정파일에 설정한 영속성 유닛을 사용해서 EntityManagerFactory 객체 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("springBoard")
 
EntityManagerFactory 객체를 이용해서 EntityManager 객체 생성
EntityManager em = emf.createEntityManager();
 
EntityManager 객체를 통해 EntityTransaction 객체 생성
EntityTransaction tx = em.getTransaction();
-->
cs


5. Entity Mapping Annotation

(1) @Entity, @Id
@Entity가 붙은 클래스를 JPA는 엔티티 클래스로 인식하고 관리하며,
JPA는 엔티티 클래스를 관련된 테이블과 자동으로 매핑 처리한다.

엔티티 클래스에서 만들어지는 엔티티는 영속성 컨텍스트에서 식별될 수 있도록,
식별자 필드를 가져야 한다. 엔티티 클래스는 반드시 식별자 필드를 가져야 하며 @Id로 등록한다.

(2) @Table
엔티티 클래스로 등록되면 JPA 는 클래스 이름과 같은 테이블을 찾아서 자동으로 매핑시킨다.
만약 엔티티 클래스와 테이블 이름이  다를 경우, @Table 을 이용해서 테이블 이름을 지정한다.

 속성

 기능

 name

 매핑될 테이블 이름을 지정

 catalog

 테이터베이스 카탈로그를 지정

 schema

 데이터베이스 스키마를 지정

 uniqueConstraints

 슈퍼키(복합키) 지정


ex) @Table(name="NEVERLAND", uniqueConstraints={@UniqueConstraint(columnNames={"SEQ", "WRITER"})})

(3) @Column
엔티티 클래스의 변수와 테이블의 칼럼을 매핑시킨다.
생략하면 변수 이름과 칼럼 이름을 동일하게 매핑한다.

속성

기능 

 name

 칼럼 이름을 지정 

 unique

 unique 제약 조건 추가 (기본값 false, unique 제약 조건을 추가하지 않음)

 nullable

 null 상태 허용 여부 설정 (기본값 false, null을 허용하지 않음) 

 insertable

 입력 쿼리를 자동 생성할 때, 이 칼럼을 포함할 것인지 지정 (기본값 true, 포함시킴) 

 updatable

 수정 쿼리를 자동 생성할 때, 이 칼럼을 포함할 것인지 지정 (기본값 true, 포함시킴)  

 columnDefinition

 이 칼럼에 대한 DDL 문을 직접 설정 

 length

 문자열 타입의 칼럼 길이를 지정 (기본값 225)

 precision

 숫자 타입의 전체 자릿수를 지정 (기본값 0) 

 scale

 숫자 타입의 소수점 자릿수를 지정 ( 기본값 0) 


ex) Column(name="BOARD_TITLE", nullable=false, length=30)


(4) @GeneratedValue
@Id 로 지정된 식별자 필드에 PK 값을 생성하여 저장할 때 사용

① generator 속성
이미 생성된 Generator 이름을 지정

② strategy 속성 (자동 생성 유형을 지정, GenerationType 지정)
ex) @GeneratedValue(strategy=GenerationType.생성전략)
     @GeneratedValue(strategy=GenerationType.SEQUENCE)

생성전략

 TABLE 

 ORM 프레임워크가 데이터베이스 테이블을 사용하여 PK 생성, PK 값 생성을 위한 별도의 테이블 설정 필요

 SEQUENCE

 Sequence Object 를 이용하여 PK 생성, 오라클 처럼 Sequence를 지원하는 데이터베이스에서 사용

 IDENTITY

 auto_increment 나 IDENTITY 를 이용하여 PK 생성, 일반적으로 MySQL 같은 데이터베이스에서 사용

 AUTO

 ORM 프레임워크가 사용 중인 데이터베이스에 맞게 자동으로 PK 생성. 생성전략을 설정하지 않았을 때의 기본값


(5) @Transient
매핑되는 칼럼이 없거나 매핑에서 제외해야하는 경우에 사용
엔티티 클래스 내의 특정 변수를 영속성 컨텍스트에서 제외시켜 버림

(6) @Temporal
java.util.Date 타입의 날짜 데이터를 매핑할 때 사용

TemporalType 속성(출력 형식 지정)
@Temporal(TemporalType.DATE) 날짜 정보만 출력
@Temporal(TemporalType.TIME) 시간 정보만 출력
@Temporal(TemporalType.TIMESTAMP) 날짜와 시간 정보 출력

(7) 엔티티 클래스 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Entity
@Table(name = "BOARD")
public class BoardVO {
    
    @Id
    @GeneratedValue
    private int seq;
    
    private String title;
    private String writer;
    private String content;
    
    @Temporal(TemporalType.DATE)
    private Date regDate = new Date();
    
    private int cnt;
    
    @Transient
    private String searchCondition;
    
    @Transient
    private String searchKeyword;
    
    @Transient
    private MultipartFile uploadFile;
 
// setter & getter
cs


6. EntityManager가 제공하는 CRUD 기능의 메소드

 메소드

기능 

 persist(Object entity)

 엔티티를 영속화 한다. (INSERT)

 merge(Object entity)

 준영속 상태의 엔티티를 영속화한다. (UPDATE)

 remove(Object entity)

 영속 상태의 엔티티를 제거한다. (DELETE) 

 find(Class<T> eintity Class, Object primaryKey)

 하나의 엔티티를 검색한다. (SELECT ONE) 

 createQuery(String qlString, Class<T> resultClass)

 쿼리 객체 생성, JPQL에 해당하는 엔티티 목록을 검색한다. (SELECT LIST) 


(1) JPQL(Java Persistence Query Language)?

객체 지향 쿼리라고 불리는 JPA 고유의 쿼리 구문이다.
SQL과 거의 유사한 문법을 제공하고 있지만, 가장 큰 차이점은
SQL이 데이터베이스의 테이블을 대상으로 하는 질의라면,
JPQL은 엔티티 객체를 대상으로 하는 질의 이다.

ex) select a from BoardVO as a order by a.seq desc;
① from 뒤의 BoardVO는 자바 클래스 이름으로 엔티티 객체를 대상으로 한다는 것을 알 수 있다.
② 반드시 as a 처럼 별칭을 지정해 주어야 하고 별칭을 질의에 사용한다.
③ as 는 생략 가능하다.

(2) DAO 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Repository
public class BoardDAOJPA {
 
    // EntityManager 객체를 주입
    @PersistenceContext
    private EntityManager em;
 
    public void insertBoard(BoardVO vo) {
        em.persist(vo);
    }
 
    public void updateBoard(BoardVO vo) {        
        em.merge(vo);
    }
 
    public void deleteBoard(BoardVO vo) {        
        em.remove(em.find(BoardVO.class, vo.getSeq()));
    }
 
    public BoardVO getBoard(BoardVO vo) {        
        return (BoardVO) em.find(BoardVO.class, vo.getSeq());
    }
 
    public List<BoardVO> getBoardList(BoardVO vo) {
   // 쿼리 객체를 생성하고 실행한 결과를 getResultList()로 받아온다    
        return em.createQuery("select b from BoardVO b order by b.seq desc").getResultList();
    }
}
cs


728x90
반응형

'Programming > Spring' 카테고리의 다른 글

Spring DI  (0) 2017.08.18
Maven / Spring 기본  (0) 2017.08.18
JPA (Java Persistence API) 기본 개념  (2) 2017.08.13
Mybatis  (0) 2017.08.13
Spring Layered Architecture  (0) 2017.08.09

댓글