참조한 강의 : Spring & Hibernate For Beginners (www.udemy.com/course/spring-hibernate-tutorial/)
이번 포스팅에서는 Hibernate ORM 에 대해 알아본다
- Persistence
: persistence 는 한글로 하면 '영속성' 을 의미한다.
영속성이란것은, 사전적으로 영원히 계속되는 성질이나 능력 이라고 정의되는데,
프로그램이 꺼지더라도, 프로그램 실행시에 사용했던 데이터들을 남겨야할 필요가 있을때가 있다.
스프링을 통한 웹 개발시에, 사용되는 데이터들에 대해서 영속성을 부여하는 방법이 있는데,
그것은 DB 와 연동시켜서 DB 에 저장하는 방법이다.
자바에서 DB 와 연동하는 방법은 JDBC 를 쓰는 것이다.
JDBC 는 Java DataBase Connectivity 의 약자로, DB 에 접근하게 해주는 API 이다.
데이터베이스를 운용할려면 당연히 SQL 을 써야 하는데,
초창기의 자바는 JDBC 를 이용하면서 자바 코드 내에 일일이 SQL 문을 써줬다.
테이블이 복잡해지고, 관계가 복잡해지면 당연히 SQL 문도 길어지고,
자바 코드와 SQL 코드가 섞이니 가독성도 매우 심하게 떨어졌다.
이런 문제들과 데이터 영속성 부여를 좀 더 원활히 하기 위해서 Persistence Framework 들이 등장했다
Persistence Framework 는 두가지로 나뉘는데,
첫번째는, SQL Mapper 이고
두번째는, ORM 이다.
SQL Mapper 는 SQL 문장과 객체를 매핑하는 방식으로
MyBatis, JdbcTemplate 등이 있으며,
ORM 은 Object Relationship Mapper 의 약자로
DB 의 테이블과 객체를 매핑하는 방식이며,
Hibernate ORM 이 있다.
- JPA, Hibernate, MyBatis ....
스프링을 배울때, 데이터 영속성 부분을 공부하다보면, JPA, Hibernate, MyBatis 등 여러 용어가 혼잡해서 나와서 다소 혼동이 올 수 있는데,
간단히 요약하면,
JPA 는 Java Persistence API 의 약자로, 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이며, 그냥 인터페이스이고, 이것 자체로 라이브러리 같은 역할을 하는게 아니다. 그냥 명세서라 보면 된다.
Hibernate ORM 은 이 JPA 를 자바 코드로 구현해놓은 것이며,
MyBatis 는 위에서도 봤듯이 ORM 이 아니라 SQL Mapper 이다.
(참고) suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/
- Hibernate ORM
여러개의 JPA 구현체 중 Hibernate 를 쓰는 이유는, 먼저 ORM 이기 때문에, 자바 코드내에 직접적으로 SQL 구문을 적을 필요가 없다. (대신에 HQL(Hibernate Query Language) 라는 것을 이용함)
또한 Hibernate 는 3 Tier 구조에서 Date Access Layer 부분을 담당하여 관리한다.
그래서 프로그래머가 좀 더 비즈니스 로직에만 집중할 수 있게 도와준다.
- Hibernate 의 구조
1) Configuration
: Configuration 부분은 hibernate.cfg.xml 파일이나 hibernate.properties 파일에 코드가 작성되며, 외부 파일없이 순수 자바 파일로만 관리될때는 @Configuration 어노테이션을 이용해서 작성된 클래스에서 관리된다.
이 부분은 SessionFactory 에서 Java Application 과 DB 와 작업할때 사용된다.
2) SessionFactory
: 사용자가 어플리케이션에서 Session 객체를 요청하면 SessionFactory 가 Configuration 을 참조해서 Session 객체를 인스턴스화해서 보내주는 역할을한다. (다음 포스팅인 CRUD 부분의 코드를 보면 이해가 될 것이다)
3) Session
: Session 은 DB 와 응용프로그램간에 상호작용을 위해 사용되는 부분으로, SessionFactory 를 거쳐서 인스턴스화 되며, org.hibernate.Session 부분에 정의되어 있다.
4) Query
: Query 는 응용프로그램이 DB 부분에 쿼리를 할 수 있도록 돕는 부분이다.
5) First-level Cache
: DB 와 상호작용하는 동안, Session 객체가 사용하는 기본 캐시를 의미한다.
이것을 별도로 session cache 라고도 부르며, 사용중인 세션 객체에 이 캐시 객체가 저장된다.
세션 객체를 통해서 DB 로 가는 모든 요청사항들은 반드시 session cache 를 거쳐가야만 한다.
또한 이 session cache 는 session 객체가 활성화 중일때만 사용 가능하다.
6) Transaction
: 데이터에 영속성을 부여하면서, 예상치 못한 상황 발생시 롤백 할 수 있게 해준다
7) Persistence Objects
: 하이버네이트에 의해서 관계형 데이터 베이스의 테이블과 연관된 행 중 하나로서 유지되는 POJO (Plain-Old Java Object) 를 의미한다.
hibernate.cfg.xml 파일에 선언되거나 혹은 hibernate.properties 파일에 선언되거나 또는
@Entity 어노테이션으로 선언되는 객체를 의미한다.
(즉, Entity Class 를 의미함)
8) Second-level cache
: 여러 세션에 걸쳐서 사용되는 캐시이며, 이 캐시는 session cache 와는 다르게, 직접 명시를 해서 써야되는 캐시로, 프로그래머가 선언시에 반드시 이 캐시에 대한 공급자를 제공해줘야 한다.
대표적인 것으로는 EhCache 가 있다.
- Hibernate ORM 설정하기
간단하게 Hibernate ORM 이 뭔지 살펴봤으니, 이클립스 IDE 에 어떻게 Hibernate ORM 을 설정할 수 있는지를 알아본다
아래의 사이트에 가면, Hibernate ORM 관련 JAR 파일들이 담긴 zip 파일을 받을 수 있다.
(현재 기준(2021-02-02) 5.4 버전이 최신 stable 버전이다)
hibernate.org/orm/releases/5.4/
zip 파일을 받은 뒤, 압축을 풀고, lib/required 폴더에 가서 JAR 파일들을 프로젝트의 lib 폴더에 복사해준다.
그리고 나서 DB Server 가 필요한데, 여기서는 MySQL 을 사용할것이다.
윈도우 유저의 경우 아래 사이트에 가면 MySQL msi 파일을 받아올 수 있다
dev.mysql.com/downloads/windows/installer/8.0.html
MySQL 을 설치해준뒤, 자바와 연결하기 위해서는 Connector/J 가 필요하다
아래의 사이트에가서 OS 선택창에서 Platform Independent 를 선택하면 zip 파일을 받아올 수 있다.
dev.mysql.com/downloads/connector/j/
Connector/J 를 받아온뒤, 압축해제하면, 아래와 같은 jar 파일이 있는데 이 파일도 이클립스 프로젝트에 복사해넣는다
그리고 해당 프로젝트의 java build path 부분에 classpath 를 추가해주면 된다.
- Annotation 을 이용한 설정방법
Hibernate ORM 을 이용해서, 자바 코드와 DB 간 연동하는 방법은 단순한편이다.
요약하면, 아래의 3개의 단계로 나뉘는데
1) hibernate.cfg.xml 파일 생성
2) Entity Class 생성
3) 테이블에 쓰일 칼럼값 지정
1)에서는 연결할 DB 에 대한 설정을 해주고
2)에서는 테이블과 클래스간 매핑을 위한 Entity Class 를 선언해야하며,
3)에서는 Entity Class 에 테이블 칼럼값으로 들어갈 필드를 선언해야한다.
이렇게 매핑시키고 난 다음 CRUD 를 이용하여 DB 와 연계된 작업을 할 수 있게 된다
(CRUD 부분은 다음 포스팅에서 설명함)
- hibernate.cfg.xml
<!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/hb_student_tracker?useSSL=false&serverTimezone=UTC</property>
<property name="connection.username">hbstudent</property>
<property name="connection.password">hbstudent</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.MySQLDialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
|
cs |
10 ~ 13 번 줄은 DB 와 연결하기 위해서 JDBC 드라이버 설정과 DB url, DB user name, DB password 를 설정해주는 부분이다.
16 번줄은 connection pool 크기를 지정하는 부분으로,
1로 설정한 이유는, 간단한 테스트용 예제이기 때문에, DB 와 연결되는 대상이 하나밖에 없기 때문이다.
(참고) Connection Pool ?
19 번 줄은 어떤 DB 와 연결할지를 설정하는 부분이다.
모든 관계형 데이터베이스가 SQL 을 사용하긴 하지만, 관계형 데이터베이스 마다 각자 약간씩 문법이 다르다
MySQL, PostgreSQL, SQLite 등 각자가 약간씩 다른 문법을 가지고 있기 때문에, 이들 중 어떤 DB 서버를 사용하는지 명시해야한다.
22번 줄은 Hibernate 가 DB 와 연결하면서 작업을 할때 SQL 구문을 만들어내는데, 이때 만들어낸 SQL 을 출력할 수 있게 할지를 설정하는 부분이다. 이는 나중에 개발 작업시에 디버깅할때 유용하게 사용된다.
25번 줄은 session context class 를 thread 로 설정한다는 의미인데, 이는 hibernate 구조에 대해서 알고 있어야한다. hibernate 구조에 대한 부분은 아래 링크 참조
joosjuliet.github.io/hibernate_structure/
* Entity Class ?
Entity Class 란, Hibernate 가 자바 클래스를 DB 의 테이블과 매핑시킬때, 바로 연결하는게 아니라, 매핑할수 있도록 자바 클래스를 Entity Class 라는 것으로 변환 시킨뒤, 테이블과 매핑시킨다.
즉, Entity Class 는 Hibernate ORM 을 통해서 자바 클래스를 테이블과 매핑시킨 객체를 의미한다.
Entity Class 를 만드는 방법은 @Entity 어노테이션을 사용하면 된다
아래는 코드 예제이다.
- Student.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="student")
public class Student {
@Id
@Column(name="id")
private int id;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email")
private String email;
public Student() {}
public Student(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
}
}
|
cs |
위의 Student 클래스는 DB 에 student 라는 테이블을 만들고, 이 테이블의 칼럼값으로 id, firstName, lastName, email 을 담기게 설정해뒀다.
코드를 보면 굳이 일일이 설명하지 않아도 너무 직관적이라 바로 알 수 있다.
여기 까지 아주 간단하게 ORM 이 무엇인지 hibernate ORM 을 어떻게 설정하고, 어노테이션을 어떻게 사용하는지 간단한 예제를 확인해봤다.
다음 포스팅에서는 hibernate 를 이용해서 CRUD 를 하는방법과 관계형 데이터베이스에 매핑시키는 여러가지 방법들에 대해서 알아본다
- References)
1. ORM : gmlwjd9405.github.io/2019/02/01/orm.html
2. Hibernate Architecture : howtodoinjava.com/hibernate-tutorials/
3. Connection Pool : linked2ev.github.io/spring/2019/08/14/Spring-3-%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80%EC%9D%B4%EB%9E%80/
4. JPA, Hibernate ORM : suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/
'Spring' 카테고리의 다른 글
Spring Framework - Persistence Context (0) | 2021.02.06 |
---|---|
Spring Framework - CRUD Using Hibernate ORM (0) | 2021.02.04 |
Spring Framework - Validation (0) | 2021.02.01 |
Spring Framework - Spring MVC Form Tag (0) | 2021.01.28 |
Spring Framework - MVC 코드 예제 (0) | 2021.01.27 |