๋ฐ์ํ
์ด๋ฒ ์๊ฐ์๋ Hiberante์ ๋ํ์ฌ ์์๋ณด๋ ค๊ณ ํ๋ค.
Java ๊ธฐ๋ฐ์ ๊ฐ๋ฐ์์ ๋ง์ด ์ฌ์ฉ๋๋ ORM (Object-Relational Mapping) ํ๋ ์์ํฌ์ด๋ค.
Java ์ธ์ด๋ก ๊ฐ๋ฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ์์ฉ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ๋์์ฃผ๋ ๋๊ตฌ ์ค ํ๋์ด๋ฉฐ,
Hibernate๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ๊ณผ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ๋งคํ์ ๋ด๋นํ์ฌ ๊ฐ๋ฐ์๊ฐ ๊ฐ์ฒด ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ ์ ์๊ฒ ํด์ค๋ค.
Hibernate ๋?
- Java ํด๋์ค๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ๋งคํํ๋ ํธ๋ฆฌํ๊ณ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ๋๋ฆฌ ์ฌ์ฉ๋๋ Java์ฉ ORM(๊ฐ์ฒด ๊ด๊ณํ ๋งคํ) ํ๋ ์์ํฌ
- ์ฃผ์์ ์ฌ์ฉํ๋ฉด ์ํฐํฐ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ฝ๊ฒ ์ ์, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์งํ๋ ๋ฐฉ๋ฒ์ ์ง์ ํ๋ฉฐ ์ํฐํฐ ํด๋์ค์ ์์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ด๋ฆฌ
- ๋ด๋ถ์ ์ผ๋ก JDBC API๋ฅผ ์ฌ์ฉ
Hibernate์ ์ฅ์
- ๊ฐ๋จํ ๊ฐ์ฒด ๋ชจ๋ธ
- Hibernate๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ธ Java์ ๊ฐ์ฒด ๋ชจ๋ธ๊ณผ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ๋งคํ์ ๊ฐ๋จํํ๋ฉฐ, ๊ฐ๋ฐ์๊ฐ ๋ณต์กํ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ์ง ์์๋ ๋๋ค.
- ๋์ ์์ฐ์ฑ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ์์ฉ์ด ๊ฐ๋จํด์ง๋ฏ๋ก ๊ฐ๋ฐ์๋ ๋น ๋ฅด๊ฒ ๊ฐ๋ฐํ ์ ์๊ณ , ๋ฐ๋ณต์ ์ธ ์์ ์ ์ต์ํํ ์ ์๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋
๋ฆฝ์ฑ
- Hibernate๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฒค๋์ ๋ ๋ฆฝ์ ์ด๋ฏ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ณ๊ฒฝํด๋ ์ฝ๋ ๋ณ๊ฒฝ์ด ํ์ํ์ง ์์ ์ ์๋ค.
- ์บ์ฑ ์ง์
- Hibernate๋ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํ ๋ค์ํ ์บ์ฑ ์ ๋ต์ ์ ๊ณตํ๋ค.
- ํธ๋์ญ์
๊ด๋ฆฌ
- Hibernate๋ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ ์ฃผ๋ฉฐ, ACID ์์ฑ์ ์ง์ํ์ฌ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ๋ค.
Hibernate์ ๋จ์
- ํ์ต ๊ณก์
- Hibernate๋ฅผ ์ ๋๋ก ํ์ฉํ๊ธฐ ์ํด์๋ ORM ๊ฐ๋ ๊ณผ Hibernate์ ์ค์ ๋ฑ์ ํ์ตํด์ผ ํ๋ฏ๋ก ์ด๊ธฐ ํ์ต ๊ณก์ ์ด ์กด์ฌํ๋ค.
- ์ฑ๋ฅ ์ด์
- ์๋ชป๋ ์ฌ์ฉ ๋๋ ๋ถ์ ์ ํ ์ค์ ์ผ๋ก ์ธํด ์ฑ๋ฅ ์ด์๊ฐ ๋ฐ์ํ ์ ์๋ค. ํนํ ํฐ ๊ท๋ชจ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์์ ์์ ์ฃผ์๊ฐ ํ์ํ๋ค.
- ๋ณต์ก์ฑ
- Hibernate๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ฐ์ํ๋ ๋ง์ ์ค์ ๊ณผ ๊ธฐ๋ฅ์ ํ๋ก์ ํธ์ ๋ฐ๋ผ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํฌ ์ ์๋ค.
- DBA์ ์ ์ฝ
- ์ผ๋ถ DBAs๋ Hibernate์ ๊ฐ์ ORM ๋๊ตฌ๋ฅผ ์ ํธํ์ง ์์ ์ ์์ผ๋ฉฐ, ํนํ ์ฑ๋ฅ ์ต์ ํ ๋ฐ ์ฟผ๋ฆฌ ํ๋ ์ธก๋ฉด์์ ์ ์ฝ์ ๊ฐ์ง ์ ์๋ค.
- ์ต์ ๊ธฐ์ ๊ณผ์ ํตํฉ ์ง์ฐ
Hibernate ์ฌ์ฉ
ํ๊ฒฝ ์ค์ ํ์ผ
- gradle ๋๋ maven ํ๋ก์ ํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก src/main ๋๋ ํฐ๋ฆฌ์์ java์ resources ํจํค์ง๋ก ๋๋๋๋ฐ resources์ ๋๋ถ๋ถ์ ํ๊ฒฝ ์ค์ ํ์ผ ๋ฐ ์ ์ ํ์ผ๋ค์ด ํฌํจ
- Hibernate์ ํ๊ฒฝ ์ค์ ๋ resources์์ ์์ฑ
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="blog">
<!-- ์ํฐํฐ ํด๋์ค -->
<class>entity.User</class>
<class>entity.UserLog</class>
<properties>
<!-- ํ์ ์์ฑ -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://175.210.112.200:3006/blog_test?autoReconnect=true"/>
<property name="javax.persistence.jdbc.user" value="bizplus"/>
<property name="javax.persistence.jdbc.password" value="bizplus"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<!-- ์ต์
์์ฑ -->
<!-- ์ฝ์์ ํ์ด๋ฒ๋ค์ดํธ๊ฐ ์คํํ๋ SQL๋ฌธ ์ถ๋ ฅ -->
<property name="hibernate.show_sql" value="true"/>
<!-- SQL ์ถ๋ ฅ ์ ๋ณด๊ธฐ ์ฝ๊ฒ ์ ๋ ฌ -->
<property name="hibernate.format_sql" value="true"/>
<!-- ์ ํ๋ฆฌ์ผ์ด์
์คํ ์์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ ์๋ ์์ฑ -->
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
๋งคํ
- Hibernate ๋งคํ์ ์๋ฐ ์ฝ๋๋ก ์์ฑํ ๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ์ข ํ ์ด๋ธ ๊ฐ์ ๊ด๊ณ ๋ฐ ํ ์ด๋ธ ์คํค๋ง ๋ฑ์ ๋งค
- ๊ฐ ํ ์ด๋ธ์ Hibernate๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฐ ์ฝ๋๋ก ์์ฑํ ํด๋์ค๋ฅผ ์ํฐํฐ(Entity)
- ํด๋์ค๋ฅผ ์ํฐํฐ๋ก ๋ง๋ค๊ธฐ ์ํด์๋ ํด๋์ค์ javax.persistence.Entity ์ด๋ ธํ ์ด์ ์ ์ ์ธํ๋ฉด ๋๋ค
- ์ํฐํฐ๋ฅผ ์์ฑํ ๋ ์ฃผ์ํด์ผ ํ ์ ์ ๋ฐ๋์ ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ๋ง๋ค์ด์ค์ผ ํ๋ค
@Entity
@Table(name = "posts")
@Getter
@Setter
@ToString
@NamedQueries({
@NamedQuery(name = "Post.findAll", query = "SELECT p FROM Post p INNER JOIN User u ON p.user.id = u.id WHERE p.deletedAt is null ORDER BY p.createdAt DESC "),
@NamedQuery(name = "Post.findById", query = "SELECT p.id, p.title, p.body FROM Post p WHERE p.id = :id")
})
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = true)
private Integer id;
private String title;
private String body;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at")
private Date createdAt;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at")
private Date updatedAt;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "deleted_at")
private Date deletedAt;
@OneToMany(mappedBy = "post", cascade = CascadeType.PERSIST)
private List<Comment> commentList = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinTable(
name = "post_tag",
joinColumns = {@JoinColumn(name = "post_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "tag_id", referencedColumnName = "id")}
)
private List<Tag> tags = new ArrayList<>();
@OneToMany(mappedBy = "post", cascade = CascadeType.PERSIST)
private List<Like> likeList = new ArrayList<>();
}
Session Factory
- EntityManagerFactory
- Hibernate์ ์ธ์ ์ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋๋ฐ ์ฌ์ฉ๋๋ ์ธํฐํ์ด์ค์ ๋๋ค. ์ด ํด๋์ค์ ์ธ์คํด์ค๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์์ ๋จ ํ๋๋ง ์กด์ฌ
package com.blog.util;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class HibernateUtil {
private static EntityManagerFactory entityManagerFactory;
static {
try{
entityManagerFactory = Persistence.createEntityManagerFactory("blog");
}catch (Exception e){
System.out.println("Hibernate Util Error");
e.printStackTrace();
}
}
public static EntityManagerFactory getEntityManagerFactory(){
return entityManagerFactory;
}
public static void closeEntityManagerFactory(){
try {
entityManagerFactory.close();
}catch (Exception e) {
System.out.println("Close EntityManagerFactory Error");
e.printStackTrace();
}
}
}
DAO
package com.blog.data.dao;
import com.blog.util.HibernateUtil;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JpaDAO<E> {
protected EntityManagerFactory entityManagerFactory = HibernateUtil.getEntityManagerFactory();
//๋ฑ๋ก(C)
public E create(E entity) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
entityTransaction.begin();
entityManager.persist(entity);
entityTransaction.commit();
return entity;
} catch (Exception e) {
e.printStackTrace();
entityTransaction.rollback();
return null;
} finally {
entityManager.close();
}
}
//์์ (U)
public E update(E entity) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
entityTransaction.begin();
entityManager.merge(entity);
entityTransaction.commit();
return entity;
} catch (Exception e) {
e.printStackTrace();
entityTransaction.rollback();
return null;
} finally {
entityManager.close();
}
}
//์กฐํ(F)
public E find(Class<E> type, Object id) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
E entity = entityManager.find(type, id);
if (entity == null) {
return null;
} else {
return entity;
}
}
//์ญ์ (D)
public boolean delete(Class<E> type, Object id) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
Object references = entityManager.getReference(type, id);
entityTransaction.begin();
entityManager.remove(references);
entityTransaction.commit();
return true;
} catch (Exception e) {
e.printStackTrace();
entityTransaction.rollback();
return false;
} finally {
entityManager.close();
}
}
//๋ฆฌ์คํธ
public List<E> findWithNamedQuery(String queryName) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNamedQuery(queryName);
List<E> result = query.getResultList();
entityManager.close();
return result;
}
public List<E> findWithNamedQuery(String queryName, Map<String, Object> parameters) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNamedQuery(queryName);
Set<Map.Entry<String, Object>> setParameters = parameters.entrySet();
for (Map.Entry<String, Object> entry : setParameters) {
query.setParameter(entry.getKey(), entry.getValue());
}
return query.getResultList();
}
public List<E> findWithNamedQuery(String queryName, String paramName, Object paramValue) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNamedQuery(queryName);
query.setParameter(paramName, paramValue);
List<E> result = query.getResultList();
entityManager.close();
return result;
}
public long countWithNamedQuery(String queryName) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNamedQuery(queryName);
long result = (long) query.getSingleResult();
entityManager.close();
return result;
}
public long countWithNamedQuery(String queryName, String paramName, Object paramValue) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNamedQuery(queryName);
query.setParameter(paramName, paramValue);
long result = (long) query.getSingleResult();
entityManager.close();
return result;
}
}
- ์ ์ฝ๋์์ entityMangaerFactory์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ ํ ์ ์๋ ๊ธฐ๋ณธ์ ์ธ CRUD ๋ฉ์๋๋ฅผ ๊ด๋ฆฌ ํ์๋ค.
- https://github.com/94-c/toy_servlet-blog-project
๋ฐ์ํ
'๐ Language > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java - Hibernate] ORM, ์์์ฑ, ์์์ฑ ์ปจํ ์คํธ๋ ๋ฌด์์ธ๊ฐ? (0) | 2024.01.22 |
---|---|
[Java] JVM(Java Virtual Machine) ์ด๋? (0) | 2024.01.13 |
[Java] Java์ ๊ธฐ๋ณธ ๊ฐ๋ (0) | 2024.01.12 |