[KH정보교육원 당산] 76일( JPA )
ORM : Object Relation Mapping (객체 관계 매핑)
- 객체는 객체대로 설계하고, 관계형 데이터베이스는 관계형 데이터베이스대로 설계한다.
- ORM 프레임워크가 중간에서 매핑해준다.
- 대중적인 언어에는 대부분 ORM 기술이 존재한다.
- ORM은 객체와 RDB 두 기둥 위에 있는 기술이다.
JAP : Java Persistence API
- 자바 ORM 기술에 대한 표준 명세로, JAVA에서 제공하는 API이다. 스프링에서 제공하는 것이 아님!
- 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이다.
- 여기서 중요하게 여겨야 할 부분은, JPA는 말 그대로 인터페이스라는 점이다. JPA는 특정 기능을 하는 라이브러리가 아니다. 스프링의 PSA에 의해서(POJO를 사용하면서 특정 기술을 사용하기 위해서)표준 인터페이스를 정해두었는데, 그중 ORM을 사용하기 위해 만든 인터페이스가 바로 JPA이다.
- 기존 EJB에서 제공되던 엔티티 빈을 대체하는 기술이다.
- ORM이기 때문에 자바 클래스와 DB테이블을 매핑한다.(sql을 매핑하지 않는다)
JAP를 이용한 DB 연동 구현
1. META-INF => persistence.xml(JPA 환경 설정 파일)
2. <persistence-unit name="해당프로젝트(JPAProject)></persistence-unit>
=> "JPAProject" 는 DAO클래스에서 EntityManagerFactory 객체 생성시 필요한 이름
3. <persistence-unit>~~</persistence-unit> 내부에는
<class></class> 를 이용하여 Entity 클래스를 등록
<class>com.jdh.spring.board.Board</class>
persistence.xml
<persistence-unit name="JPAProject">
<class>com.jdh.spring.board.Board</class>
<properties>
<!-- 필수 -->
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:XE"/>
<property name="javax.persistence.jdbc.user" value="spring_test"/>
<property name="javax.persistence.jdbc.password" value="ekgns00"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect"/>
<!-- 선택 -->
<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>
properties 내부에 값 설정
선택 부분은 필요한 부분을 따로 등록하여 사용한다.
Board클래스
@Entity
@Table(name = "BOARD") //DB 테이블명과 동일하게 설정되었을 경우 생략 가능
public class Board {
@Id
@GeneratedValue
private int seq;
private String title;
private String writer;
private String content;
//DB와 타입을 맞춰 주기 위한 어노테이션
@Temporal(TemporalType.DATE)
private Date regDate;
private int cnt;
public Board() {
super();
}
getter / setter 메서드
어노테이션 | 의미 |
@Entity | @Entity가 붙은 클래스는 테이블과 매핑 된다. |
@Table | 엔티티와 관련된 테이블을 매핑 |
@Id | 엔티티 클래스의 필수 어노테이션!! 특정 변수를 테이블의 기본 키와 매핑 |
@GenerateValue | @Id가 선언된 필드에 기본 키를 자동으로 생성하여 할당 |
@Temporal | 날짜 타입의 변수에 선언하여 날짜 타입을 매핑 (TIME, DATE, TIMESTAMP 중 하나 성택할 수 있다.) |
실제 연동 과정
public class BoardServiceClient {
public static void main(String[] args) {
//EntityManager 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPAProject");
EntityManager em = emf.createEntityManager();
//Transaction 생성
EntityTransaction tx = em.getTransaction();
try {
tx.begin(); // 트랜잭션 시작
Board board = new Board();
board.setTitle("JPA 제목");
board.setWriter("작성자");
board.setContent("본문");
//글 등록
em.persist(board);
String jpql = "SELECT b FROM board b ORDER BY b.seq DESC";
List<Board> boardList = em.createQuery(jpql,Board.class).getResultList();
for(Board bd : boardList){
System.out.println("출력 값 : " + bd);
}
tx.commit(); //트랜잭션 적용
} catch (Exception e) {
e.printStackTrace();
tx.rollback(); //원래대로
} finally {
em.close(); //자원 해제
}
emf.close();
}
}
persistence 메서드
메서드 | 기능 설명 |
persist(Object Entity) | 엔티티를 영속화 한다.(INSERT) |
merge(Object Entity) | 준영속 상태의 엔티티를 영속화 한다.(UPDATE) |
remove(Object Entity) | 영속 상태의 엔티티를 제거한다.(DELETE) |
find(Class<T> entityClass, Object PrimaryKey) | 하나의 엔티티를 검색한다.(SELECT ONE) |
createQuery(String qlString,Class<T> resultClass) | JPQL에 해당하는 엔티티 목록을 검색한다.(SELECT LIST) |
여기서 트랜잭션 한번 더 정리
트랜잭션(Transaction)은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미
스프링과 JPA 연동
스프링 프로젝트 -> properties -> Project Facets -> JPA추가
그러면 META-INF 쪽에 persistence.xml 파일이 추가된것을 알 수 있다.
기존에 사용했던 스프링 프로젝트를 사용함으로 DB연동 코드가 생략되었다.(applicataionContext.xml)에 설정되어있음
<class>com.freeflux.biz.board.BoardVO</class>
<properties>
<!-- DB연결은 spring 설정에서 해놨기 때문에 이 부분에서는 오라클 설정만 해준다. -->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect"/>
<!-- 선택 -->
<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>
applicationContext.xml에 코드 추가
<!-- 스프링과 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="dateSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
2개의 클래스를 스프링에 등록 시켜줘야한다.(JpaVendorAdapter클래스, EntityManagerFactoryBean)
VO객체를 기존의 VO클래스를 사용함으로 xml로 보내지게 설정해놨던 VO 클래스를 JPA가 읽을 수 있게 어노테이션을 바꿔준다.
@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;
getter / setter
트랜잭션 수정
<!-- 기존에 사용했던 방식 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 변경된 코드 -->
<bean id="txManager" class="org.springframework.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
DataSourceTransactionManager
: SpringJDBC나 Mybatis를 이용하여 DB를 연동 할 경우에 사용하는 트랜잭션 관리자
JpaTransactionManager
: JPA를 이용하여 DB를 연동할 경우 사용하는 트랜잭션 관리자
JPA 기반의 DAO클래스 구현
EntityManager 객체를 사용하여 구현한다.
스프링 컨테이너가 제공하는 EntityManager 사용 ( EntityManagerFactory가 제공하는거 아님!! )
@Repository
public class BoardDAOJPA {
@PersistenceContext
private EntityManager em;
public BoardDAOJPA() {
}
public void insertBoard(BoardVO vo){
em.persist(vo);
}
public void updateBoard(BoardVO vo){
em.merge(vo);
}
.
.
.
.
.
}
@PersistenceContext
: 스프링 컨테이터가 관리하는 EntityManager 객체를 의존성 주입할 때 사용하는 어노테이션
**
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
LocalContainerEntityManagerFactoryBean 클래스의 객체를 이용하여 @PersistenceContext 가 설정된 EntityManager 타입의 변수에 객체를 의존성 주입
'Learn > KH정보교육원' 카테고리의 다른 글
[KH정보교육원 당산] 78일 (Spring Boot - ORM과 JPA) (0) | 2021.07.07 |
---|---|
[KH 정보교육원 당산] 77일 ( Spring Boot - IntelliJ IDEA / MariaDB) (0) | 2021.07.07 |
[KH정보교육원 당산] 75일(AJAX - To-Do-List ) (0) | 2021.07.02 |
[KH정보교육원 당산] 연습문제9 (인터페이스 구현) (0) | 2021.07.01 |
[KH정보교육원 당산] 74일 (Spring흐름 및 Ajax를 활용한 To-Do list) (0) | 2021.06.30 |