티스토리 뷰

spring

day5 class06 스프링과 JPA 연동

일상다반ㅅㅏ 2019. 3. 3. 17:08

스프링과 JPA연동을 위해 project facets를 jpa 프로젝트로 변환해야한다고 교재엔 나와있지만 역시나 없으니 넘어간다.


1. 라이브러리 내려받기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- pom.xml -->
 
<!-- JPA, 하이버네이트 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.1.0.Final</version>
</dependency>
 
<!-- orm : 이건 갑자기 추가가 됐네?? -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>${org.springframework-version}</version>
</dependency>
cs



2. jPA 설정 파일 작성

- jpa 설정 파일인 persistence.xml 파일은 applicationContext.xml에 모두 등록하기 때문에 추가하지 않아도 된다.



3. 엔티티 매핑 설정

- @Entity, @Table, @Id, @GenerateValue 같은 엔티티 관련 어노테이션을 추가했다.

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.springbook.biz.board;
 
 
import java.util.Date;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
 
import org.springframework.web.multipart.MultipartFile;
 
@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;
    private int cnt;
    @Transient
    private String searchCondition;
    @Transient
    private String searchKeyword;
    @Transient
    private MultipartFile uploadFile;
    
    public int getSeq() {
        return seq;
    }
    public void setSeq(int seq) {
        this.seq = seq;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getWriter() {
        return writer;
    }
    public void setWriter(String writer) {
        this.writer = writer;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public Date getRegDate() {
        return regDate;
    }
    public void setRegDate(Date regDate) {
        this.regDate = regDate;
    }
    public int getCnt() {
        return cnt;
    }
    public void setCnt(int cnt) {
        this.cnt = cnt;
    }
    
    public String getSearchCondition() {
        return searchCondition;
    }
    public void setSearchCondition(String searchCondition) {
        this.searchCondition = searchCondition;
    }
    public String getSearchKeyword() {
        return searchKeyword;
    }
    public void setSearchKeyword(String searchKeyword) {
        this.searchKeyword = searchKeyword;
    }
    public MultipartFile getUploadFile() {
        return uploadFile;
    }
    public void setUploadFile(MultipartFile uploadFile) {
        this.uploadFile = uploadFile;
    }
    
    @Override
    public String toString() {
        return "BoardVO [seq=" + seq + ", title=" + title + ", writer=" + writer + ", content=" + content + ", regDate=" + regDate + ", cnt=" + cnt + "]";
    }
}
 
cs



4. applicationContext.xml 설정

4-1. 스프링과 JPA연동 설정

- JpaVendorAdapter클래스는 실제로 DB 연동에 사용할 JPA벤더를 지정할 때 사용하는데, 우리는 하이버네이트를 JPA 구현체로 사용하고 있으므로 JpaVendorAdapter 클래스로 HibernateJpaVendorAdapter를 등록한다.

- 이전 강의에선 테스트 소스에 직접 입력했던 EntityManagerFactoryBean클래스를 설정파일에 등록한다.

- LocalContainerEntityManagerFactoryean클래스는 JPA를 이용하여 DAO 클래스를 구현하기 위해 최종적으로 EntityManager 객체를 생성해 준다. DataSource와 JpaVendorAdapter를 의존성 주입하고 영속성 유닛 관련된 설정을 같이 처리하여 persistence.xml의 설정들을 등록할 수 있다.

4-2. 트랜잭션 설정

- JPA를 이용하여 DB 연동을 처리하고 있으므로 트랜잭션 관리자를 변경해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- applicationContext.xml -->
 
<!-- Transaction 설정 -->
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
 
<!-- 스프링과 JPA 연동 설정 -->
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
    <property name="packagesToScan" value="com.springbook.biz.board"></property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.use_sql_comments">false</prop>
            <prop key="hibernate.id.new_generator_mappings">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
        </props>
    </property>
</bean>
cs



5. DAO 클래스 구현

- 이전 강의에선 테스트 소스에서 EntityManagerFactory로부터 EntityManager 객체를 직접 얻어냇지만, 스프링과 연동할 때는 스프링 컨테이너에서 제공하는 EntityManager를 사용한다.

- @PersistenceContext는 스프링 컨테이너가 관리하는 EntityManager 객체를 의존성 주입할 때 사용하는 어노테이션이다.

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
51
52
package com.springbook.biz.board.impl;
 
import java.util.List;
 
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
 
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
 
import org.springframework.stereotype.Repository;
 
import com.springbook.biz.board.BoardVO;
 
@Repository
public class BoardDAOJPA {
    
    @PersistenceContext
    private EntityManager em;
    
    // CRUD 기능의 메소드 구현
    // 글 등록
    public void insertBoard(BoardVO vo) {
        System.out.println("===> jpa로 insertBoard() 기능 처리");
        em.persist(vo);
    }
    
    // 글 수정
    public void updateBoard(BoardVO vo) {
        System.out.println("===> jpa로 updateBoard() 기능 처리");
        em.merge(vo);
    }
    
    // 글 삭제
    public void deleteBoard(BoardVO vo) {
        System.out.println("===> jpa로 deleteBoard() 기능 처리");
        em.remove(em.find(BoardVO.class, vo.getSeq()));
    }
    
    // 글 상세 조회
    public BoardVO getBoard(BoardVO vo) {
        System.out.println("===> jpa로 getBoard() 기능 처리");
        return (BoardVO) em.find(BoardVO.class, vo.getSeq());
    }
    
    // 글 목록 조회
    public List<BoardVO> getBoardList(BoardVO vo) {
        System.out.println("===> jpa로 getBoardList() 기능 처리");
        return em.createQuery("from BoardVO b order by b.seq desc").getResultList();
    }
}
 
cs



6. BoardSericeImpl 클래스 수정

- JPA로 DB 연동을 위해 수정한다.

1
2
3
4
5
@Service("boardService")
public class BoardServiceImpl implements BoardService {
 
    @Autowired
    private BoardDAOJPA boardDAO;
cs


--------------------------------------------------------------------------------

약 3달만에 스프링 퀵 스타트 교재 실습을 마쳤다.
스프링에 대해 많이 배워서 좋긴한데
junit나 게시판 소스에 세세한 기능까진 다 잡아주진 않아 살짝 아쉬운 감이 든다.