빠에야는 개발중
스프링 퀵 스타트 : chap 5-2 본문
JPA
이번에는 JPA를 사용해보자. ORM은 쿼리를 자동으로 생성해주는 등 편리한 점이 많기 때문에 꼭 써봐야겠다고 생각했다.
입문
저번처럼 스프링에 적용하기 전에 연습을 해보자. 먼저 maven 프로젝트를 하나 생성하고, 디펜던시 설정을 해준다.
Project facets에 JPA를 체크하면 persistence.xml 파일이 자동으로 생성된다. 여기에 클래스 등록을 해준다.
1 2 3 4 5 | <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" 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_1.xsd"> <persistence-unit name="springboard"> <class>com.springbook.biz.board.BoardVO</class> //생략 | cs |
다음은 엔티티 작성이다. @Entity 어노테이션을 사용하여 VO와 거의 동일하게 작성해준다.
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 | package com.springbook.biz.board; import java.io.Serializable; 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; /** * Entity implementation class for Entity: Board * */ @Entity @Table(name = "BOARD") public class Board { @Id @GeneratedValue private int seq; private String title; private String writer; private String content; @Temporal(TemporalType.DATE) private Date regDate; private int cnt; //getter, setter, toString | cs |
여기서 몇가지 어노테이션에 대해서 짚고 넘어가자.
1. @Entity : 엔티티 클래스를 설정하기 위한 어노테이션이다.
2. @Table : 엔티티와 관련된 테이블을 매핑한다.
3. @Id : 엔티티 클래스의 필수 어노테이션으로, 테이블의 기본 키와 매핑되는 변수를 지정한다.
4. @GeneratedValue : @Id가 선언된 필드에 기본 키를 자동으로 생성하여 할당한다.
5. @Temporal : 날짜 관련 변수를 선언하여 매핑할 때 사용한다.
마지막으로 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 | <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" 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_1.xsd"> <persistence-unit name="JPAProject"> <class>com.springbook.biz.board.Board</class> <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"/> <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="false"/> <property name="hibernate.id.new_generator_mappings" value="true"/> <property name="hibernate.hbm2ddl.auto" value="create"/> </properties> </persistence-unit> </persistence> | cs |
테스트를 해보면 다음과 같이 Hibernate가 찍는 로그들을 볼 수 있다.
persistence.xml에 설정한 hibernate 설정을 알아보자.
1. hibernate.show_sql : 쿼리를 출력한다.
2. hibernate.format_sql : 쿼리를 예쁘게 출력한다.
3. hibernate.use_sql_comments : 쿼리에 포함된 주석을 함께 출력한다.
4. hibernate.id.new_generator_mappings : 새로운 키 생성 전략을 사용한다.
5. hibernate.hbm2ddl.auto : DDL 구문을 자동으로 처리할지 지정한다.
스프링과 연동
이제 스프링과 연동해보자. 우선 스프링 프로젝트의 project facet에서 jpa를 체크한다.
다음 디펜던시를 설정해준다.
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- JPA, Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.1.0.Final</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${org.springframework-version}</version> </dependency> | cs |
자동 생성된 persistence.xml 파일을 작성해준다. dataSource에 관련된 코드는 이미 applicationContext.xml에 있기 때문에 작성할 필요가 없다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" 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_1.xsd"> <persistence-unit name="springboard"> <class>com.springbook.biz.board.BoardVO</class> <properties> <!-- 필수 속성 --> <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="false"/> <property name="hibernate.id.new_generator_mappings" value="true"/> <property name="hibernate.hbm2ddl.auto" value="create"/> </properties> </persistence-unit> </persistence> | cs |
BoardVO의 매핑 설정을 해준다. 간단한 어노테이션 작업만 해주면 된다.
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 | 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; import com.fasterxml.jackson.annotation.JsonIgnore; @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; // | cs |
applicaionContext.xml에서 연동 설정을 해준다.
1 2 3 4 5 6 7 | <!-- 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> </bean> | cs |
이전에 실습한 트랜잭션 처리 부분을 이제 JPA가 하기 때문에 클래스를 변경해준다.
1 2 3 4 | <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> | cs |
마지막으로 DAO 부분을 JPA에 맞게 수정해주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Repository("BoardDAO") public class BoardDAO { @PersistenceContext private EntityManager em; public void insertBoard(BoardVO vo) { System.out.println("insertBoard() 기능 처리"); em.persist(vo); } public void updateBoard(BoardVO vo) { System.out.println("updateBoard() 기능 처리"); em.merge(vo); } // | cs |
책을 끝내며
“하루 7시간 5일 완성”이라는 슬로건을 단 이 책은 내 손에서 15일에 가까운 시간을 걸려 그 목표를 이루게 되었다… 오래 걸린 만큼 더 확실하게 내용들을 기억하고 싶은 마음이었으나 쉽게 이루어질 것 같지는 않고 앞으로도 개발을 계속 하면서 확인해나가야 할 것 같다. 그래도 처음 생각했던 “잊었던 스프링을 기억해내고 새로운 기술들을 익혀보자”라는 목표는 어느 정도 달성한 것 같다고 생각했다. 덕분에 써보겠다고 생각만 했던 AOP나 JPA 등의 기술을 얕게나마 체험 해볼 수 있었으니까.
앞으로는 gradle이나 jenkins 등 배포에 관련된 기술들을 추가해 나가며 실제 서비스를 운용하는 공부를 할 생각이다.
'공부 > 스프링' 카테고리의 다른 글
롬복(lombok) (0) | 2018.02.26 |
---|---|
Controller의 String 리턴 (0) | 2018.02.05 |
스프링 퀵 스타트 : chap 5-1 (0) | 2018.02.04 |
스프링 퀵 스타트 : chap 4-2 (1) | 2018.02.01 |
스프링 퀵 스타트 : chap 4-1 (1) | 2018.01.31 |