티스토리 뷰
1. 이 포스트는 반복되는 형태의 저장 속성에 효율적으로 사용가능한 @Embedded 관한 포스팅이다.
2. 하이버네이트는 다룰 수 있는 Type을 Entity와 그 외로 나눌 수 있다.
2-1 Entity는 데이터베이스 테이블을 표현하는 하나의 자바클래스로 @Entity로 수식하고 테이블로 인식한다.
2-2 그 외로 Value값 String, Integer, Double 같은 일반적인 자바와 데이터베이스의 값들이 있다.
3. Value 값들의 분류
3-1 일반적인 String ,Integer, Double, Date 같은 데이터베이스의 속성 값들
3-2 두번째는 @ElementCollection을 사용하는 Collection
2-4 마지막으로는 이런 Value 값들의 집합인 Embedded
4. Embedded는 value값들의 집합으로 값들의 모음일 뿐이다.
4-1 자바에서는 반복되는 형식을 클래스로 표현할 수 있고 편리하게 사용할 수 있다.
4-2 배송정보, 과금정보, 거주지, 회사주소, 이런 중복되는 데이터는 Address 클래스로 따로 뽑을 수 있다.
4-3 부모데이터베이스와 Embeddable 데이터베이스는 has관계를 가진다.
5. Annotation 설명
5-1 @Embeddable - 클래스에 붙여지는 것으로 이 클래스는 Entity에 집어 넣을 수 있다는 의미다.
5-2 @Embedded - 속성값에 붙이고 @Embeddable이 붙은 클래스의 속성을 사용한다. 없어도 동작한다.
6. 프로젝트 생성
6-1 maven archetype quickstart 1.4로 생성하였다.
6-2 hibernate-core, mysql-connector-java, lombok 라이브러리를 추가한다.
<?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>pe.pilseong</groupId>
<artifactId>hibernate_embedded</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hibernate_embedded</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.17.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
6-3 데이터베이스 연결을 위한 hibernate.cfg.xml파일을 classpath:root에 복사한다.
6-3-1 클래스 패스로 가장 편한 곳이 src/main/java 폴더이다.
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/advanced_hibernate?useSSL=false&serverTimezone=Asia/Seoul</property>
<property name="connection.username">root</property>
<property name="connection.password">rort</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
7. 코드 작성
7-1 Student Entity
7-1-1 @Embedded로 Address를 정의하고 있다.
7-1-2 인자 3개 짜리 생성자를 사용하고 있으므로 @NoArgsConstructor를 붙여야 한다.
package pe.pilseong.hibernate_embedded.entity;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "student")
@Data
@NoArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@Embedded
private Address address;
public Student(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
}
7-2 Address Embeddable Value
7-2-0 클래스 선언 위에 @Embeddable을 지정한다.
7-2-1 Value클래스이기 때문에 @Id같은 것은 들어올 수 없다.
7-2-2 인자 4개 짜리 생성자이기 때문에 @NoArgsConstructor가 있어야 한다.
package pe.pilseong.hibernate_embedded.entity;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import lombok.Data;
import lombok.NoArgsConstructor;
@Embeddable
@Data
@NoArgsConstructor
public class Address {
@Column(name = "street")
private String street;
@Column(name = "city")
private String city;
@Column(name = "state")
private String state;
@Column(name = "country")
private String country;
public Address(String street, String city, String state, String country) {
this.street = street;
this.city = city;
this.state = state;
this.country = country;
}
}
8. 실행결과
8-1 실행코드
package pe.pilseong.hibernate_embedded;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import pe.pilseong.hibernate_embedded.entity.Address;
import pe.pilseong.hibernate_embedded.entity.Student;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure()
.addAnnotatedClass(Student.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();
Student student = new Student("Pilseong", "Heo", "heops79@gmail.com");
Address address = new Address("siminro gold", "Seongnam", "Gyeunggi", "South Korea");
student.setAddress(address);
session.save(student);
session.getTransaction().commit();
factory.close();
}
}
8-2 테이블 결과
8-3 테이블 구조
9. 재활용 예시
9-1 Shipping Entity 작성
9-1-1 기존의 Address을 재사용하고 있는데 Entity에서 사용될 이름을 변경하여 지정하고 있다.
9-1-2 name에는 기존 속성이름, @Column(name 에는 사용을 원하는 속성이름을 입력한다.
package pe.pilseong.hibernate_embedded.entity;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "shipping_product")
@Data
@NoArgsConstructor
public class Shipping {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="street",
column=@Column(name = "shipping_street")),
@AttributeOverride(name="city",
column=@Column(name = "shipping_city")),
@AttributeOverride(name="state",
column=@Column(name = "shipping_state")),
@AttributeOverride(name="country",
column=@Column(name = "shipping_country"))
})
private Address address;
@Column(name = "product_name")
private String product;
@Column(name = "quantity")
private Integer quantity;
public Shipping(Address address, String product, Integer quantity) {
this.address = address;
this.product = product;
this.quantity = quantity;
}
}
9-2 실행코드
9-2-1 하나의 주소를 생성하고 student entity와 shipping entity에 모두 사용하고 있다.
package pe.pilseong.hibernate_embedded;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import pe.pilseong.hibernate_embedded.entity.Address;
import pe.pilseong.hibernate_embedded.entity.Shipping;
import pe.pilseong.hibernate_embedded.entity.Student;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure()
.addAnnotatedClass(Student.class)
.addAnnotatedClass(Shipping.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();
Student student = new Student("Pilseong", "Heo", "heops79@gmail.com");
Address address = new Address("siminro gold", "Seongnam", "Gyeunggi", "South Korea");
Shipping shipping = new Shipping(address, "computer", 5);
student.setAddress(address);
session.save(student);
session.save(shipping);
session.getTransaction().commit();
factory.close();
}
}
9-3 테이블 결과
9-4 테이블 구조
'Spring > Hibernate' 카테고리의 다른 글
Hibernate Advanced : 상속 매핑 - Single Table Strategy (0) | 2020.06.05 |
---|---|
Hibernate Advanced : Enum 사용하기 (0) | 2020.06.05 |
Hibernate Advanced : SortedMap, SortedSet 사용하기 (0) | 2020.06.05 |
Hibernate Advanced : javax.persistence @OrderBy 사용하기 (0) | 2020.06.04 |
Hibernate Advanced : @ElementCollection Map 사용하기 (0) | 2020.06.04 |
- Total
- Today
- Yesterday
- 도커 개발환경 참고
- AWS ARN 구조
- Immuability에 관한 설명
- 자바스크립트 멀티 비동기 함수 호출 참고
- WSDL 참고
- SOAP 컨슈머 참고
- MySql dump 사용법
- AWS Lambda with Addon
- NFC 드라이버 linux 설치
- electron IPC
- mifare classic 강의
- go module 관련 상세한 정보
- C 메모리 찍어보기
- C++ Addon 마이그레이션
- JAX WS Header 관련 stackoverflow
- SOAP Custom Header 설정 참고
- SOAP Custom Header
- SOAP BindingProvider
- dispatcher 사용하여 설정
- vagrant kvm으로 사용하기
- git fork, pull request to the …
- vagrant libvirt bridge network
- python, js의 async, await의 차이
- go JSON struct 생성
- Netflix Kinesis 활용 분석
- docker credential problem
- private subnet에서 outbound IP 확…
- 안드로이드 coroutine
- kotlin with, apply, also 등
- 안드로이드 초기로딩이 안되는 경우
- navigation 데이터 보내기
- 레이스 컨디션 navController
- raylib
- 상속
- Rest
- 설정하기
- Spring Security
- 스프링
- Many-To-Many
- Spring
- jsp
- hibernate
- one-to-many
- crud
- 외부파일
- spring boot
- MYSQL
- login
- RestTemplate
- WebMvc
- Angular
- XML
- form
- one-to-one
- Security
- 자바
- 로그인
- Validation
- 스프링부트
- 하이버네이트
- 매핑
- 설정
- mapping