(spring data jpa)식별자(@id, primary key) 자동 생성, @generatedvalue의 strategy...

14
JPA 식별자 자동 생성(@GeneratedValue) JPA 식별자 자동 생성(@GeneratedValue) 식별자 자동생성은 @GeneratedValue 어노테이션으로 지정한다. 복합키 보다는 대행키(인공키, Artifitial Key) 사용을 권장한다. @GeneratedValue의 strategy 속성에 값을 지정해 여러 가지 식별자 자동 생 성 전략을 선택할 수 있는데 AUTO, TABLE, SEQUENCE, IDENTITY 값으로 지정 한다. 이 값들은 열거형인 GenerationType에 정의되어 있다. GenerationType.AUTO : 데이터베이스에 관계없이 식별자를 자동 생성 하라 는 의미, DB가 변경되더라도 수정할 필요 없다.

Upload: 3-2

Post on 15-Apr-2017

670 views

Category:

Education


1 download

TRANSCRIPT

Page 1: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

JPA 식별자 자동 생성(@GeneratedValue)

JPA 식별자 자동 생성(@GeneratedValue)

식별자 자동생성은 @GeneratedValue 어노테이션으로 지정한다.

복합키 보다는 대행키(인공키, Artifitial Key) 사용을 권장한다.

@GeneratedValue의 strategy 속성에 값을 지정해 여러 가지 식별자 자동 생

성 전략을 선택할 수 있는데 AUTO, TABLE, SEQUENCE, IDENTITY 값으로 지정

한다. 이 값들은 열거형인 GenerationType에 정의되어 있다.

GenerationType.AUTO : 데이터베이스에 관계없이 식별자를 자동 생성 하라

는 의미, DB가 변경되더라도 수정할 필요 없다.

Page 2: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

자동 선택

@Id

@GeneratedValue(strategy=GenerationType.AUTO)

@Column(name="USER_ID")

protected Long userId;

JPA 공급자에 따라 기본설정이 다름

Oracle을 사용할 경우 SEQUENCE가 기본

MS SQL Server의 경우 IDENTITY가 기본

위 예문의 경우 오라클이라면 하이버네이트 글로벌 시퀀스(hibernate_sequence)를

사용하므로 엔티티에서 두 군데 이상 AUTO로 사용한다면 시퀀스를 별도로 만들

고 명시적으로 SequenceGenerator를 기술하여 사용하는 것이 좋다.

GenerationType.TABLE : 가장 유연하고 이식성이 좋은 방법으로 키를 위한

테이블이 생성되어 있어야 하며, ID 생성 테이블은 두 개의 칼럼을 반드시 가

져야 한다. 처음 컬럼은 특정 시퀀스를 식별하는데 사용되는 문자열 타입이고

모든 Generator를 위한 위한 주키다. 두 번째 칼럼은 생성되고 있는 실제 ID

값인 시퀀스를 저장하는 숫자 타입으로 이 칼럼에 저장되는 값은 시퀀스에 할

당되었던 마지막 값이 된다. 하나의 테이블에 여러 식별자 값을 저장할 수 있

으며 오라클의 경우 아래처럼 사용하면 된다.

1. 식별자용 테이블 생성(JPA에서 자동생성)

CREATE TABLE SEQ_TABLE

(SEQ_NAME VARCHAR2(100) NOT NULL PRIMARY KEY,

SEQ_VALUE NUMBER NOT NULL);

2. 식별자 테이블 초기화(JPA에서 자동생성)

INSERT INTO SEQ_TABLE VALUES ('USER_SEQ', 1);

3. TableGenerator 생성, @GeneratedValue 사용

@TableGenerator (name="MY_GENERATOR", table="SEQ_TABLE",

Page 3: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

pkColumnName="SEQ_NAME",

valueColumnName="SEQ_VALUE", pkColumnValue="USER_SEQ")

@Entity

public class User {

@GeneratedValue(strategy=GenerationType.TABLE, generator="MY_GENERATOR")

@Column(name="USER_ID")

@Id

protected Long userId;

GenerationType.SEQUENCE : DB에서 생성해 놓은 시퀀스를 이용하는 방법으

로 오라클, DB2, PostgreSQL, H2 데이터베이스 등에서 사용한다.

1. 오라클 DB에 시퀀스 생성

CREATE SEQUENCE USER_SEQ;

2. 엔티티에 SequenceGenerator, @GeneratedValue 지정

@SequenceGenerator(name="USER_SEQ_GENERATOR",

sequenceName="USER_SEQ")§

@Id

@Entity

public class User {

@GeneratedValue(strategy=GenerationType.SEQUENCE,

generator="USER_SEQ_GENERATOR")

@Column(name="USER_ID")

protected Long userId;

GeneratedType.IDENTITY : MySQL, MS-SQL 처럼 DB 자체적으로 식별자 칼럼

에 자동증분 속성이 있는 경우에 사용한다. 엔티티의 주키 컬럼을 위한 정의

는 DB 스키마 정의의 일부분으로 정의되어야 한다.

[GenerationType.TABLE, 오라클 예제]

STS에서 File -> New -> Spring Stater Project 프로젝트 이름 : GeneratedValueTest

Page 4: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

다음화면에서 SQL : JPA, Web : Web 선택

1. pom.xml

<?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>com.example</groupId>

<artifactId>demo</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>

<name>GeneratedValueTest</name>

<description>Demo project for Spring Boot</description>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.4.1.RELEASE</version>

<relativePath /> <!-- lookup parent from repository -->

</parent>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

<dependency>

Page 5: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<!-- JSP, JSTL 사용위해 -->

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jstl</artifactId>

</dependency>

<dependency>

<groupId>org.apache.tomcat.embed</groupId>

<artifactId>tomcat-embed-jasper</artifactId>

<scope>provided</scope>

</dependency>

<!-- DriverSpy -->

<dependency>

<groupId>org.bgee.log4jdbc-log4j2</groupId>

<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>

<version>1.16</version>

</dependency>

<!-- for oracle -->

<dependency>

<groupId>com.oracle</groupId>

<artifactId>ojdbc6</artifactId>

Page 6: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

<version>11.1.0.7.0</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

<repositories>

<repository>

<id>oracle</id>

<name>ORACLE JDBC Repository</name>

<url>https://maven.oracle.com</url>

</repository>

</repositories>

</project>

2. application.properties

spring.datasource.platform=oracle

spring.datasource.sql-script-encoding=UTF-8

spring.datasource.url=jdbc:log4jdbc:oracle:thin:@localhost:1521:onj

spring.datasource.username=test

spring.datasource.password=test

#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

spring.datasource.driver-class-name = net.sf.log4jdbc.sql.jdbcapi.DriverSpy

spring.jpa.show-sql=true

Page 7: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

spring.jpa.hibernate.ddl-auto=create

#hibernate config

spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect

logging.level.jpa=DEBUG

#view

spring.mvc.view.prefix=/WEB-INF/jsp/

spring.mvc.view.suffix=.jsp

3. log4jdbc.log4j2.properties

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

log4jdbc.dump.sql.maxlinelength=0

4. logback.xml

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

<encoder>

<pattern>%d{yyyyMMdd HH:mm:ss.SSS} [%thread] %-3level %logger{5} -

%msg %n</pattern>

</encoder>

</appender>

<logger name="jdbc" level="OFF"/>

<logger name="jdbc.sqlonly" level="DEBUG" additivity="false">>

<appender-ref ref="STDOUT" />

</logger>

Page 8: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

<logger name="jdbc.sqltiming" level="INFO" additivity="false">>

<appender-ref ref="STDOUT" />

</logger>

<logger name="jdbc.resultsettable" level="DEBUG" additivity="false">>

<appender-ref ref="STDOUT" />

</logger>

<root level="INFO">

<appender-ref ref="STDOUT" />

</root>

</configuration>

5. User.java

package com.example.model;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.TableGenerator;

@TableGenerator(name = "MY_GENERATOR", table = "SEQ_TABLE",

pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_VALUE",

pkColumnValue = "USER_SEQ")

@Entity(name="MyUser")

public class User {

@GeneratedValue(strategy = GenerationType.TABLE, generator =

"MY_GENERATOR")

@Id

Page 9: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

private Long userId;

@Column

private String userName;

public User(String userName) {

this.userName = userName;

}

public User() {}

public Long getUserId() {

return userId;

}

public void setUserId(Long userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

}

6. UserRepository.java

Page 10: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

package com.example.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.example.model.User;

public interface UserRepository

extends JpaRepository<User, Long> {

}

7. UserService.java

package com.example.service;

import java.util.List;

import com.example.model.User;

public interface UserService {

User get(Long userId);

User save(User user);

List<User> getAll();

}

8. UserServiceImpl.java

package com.example.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

Page 11: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

import com.example.model.User;

import com.example.repository.UserRepository;

@Service

public class UserServiceImpl implements UserService {

@Autowired

UserRepository userRepository;

@Override

public User get(Long userId) {

return userRepository.findOne(userId);

}

@Override

public User save(User user) {

return userRepository.save(user);

}

@Override

public List<User> getAll() {

return userRepository.findAll();

}

}

9. UserController.java

package com.example.controller;

import java.util.List;

Page 12: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RestController;

import com.example.model.User;

import com.example.service.UserService;

@RestController

public class UserController {

@Autowired

private UserService userService;

@RequestMapping(value="/get/{userId}", method=RequestMethod.GET)

public User get(@PathVariable Long userId) {

return userService.get(userId);

}

@RequestMapping(value="/save/{userName}",

method=RequestMethod.GET)

public User save(@PathVariable String userName) {

return userService.save(new User(userName));

}

@RequestMapping(value="/getall", method=RequestMethod.GET)

public List<User> getAll() {

return userService.getAll();

}

}

10. 오라클에 식별자를 위한 테이블 및 데이터 생성

Page 13: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원

SQL> create table seq_table (

2 seq_name varchar2(100) primary key,

3 seq_value number not null);

테이블이 생성되었습니다.

SQL> INSERT INTO SEQ_TABLE VALUES ('USER_SEQ', 1);

1 개의 행이 만들어졌습니다.

SQL> commit;

커밋이 완료되었습니다.

11. 실행결과

Page 14: (Spring Data JPA)식별자(@Id, Primary Key) 자동 생성, @GeneratedValue의 strategy 속성,GenerationType.AUTO,GenerationType.TABLE, GenerationType.IDENTITY_스프링프레임워크/JPA재직자기초에서실무교육학원