Skip to content

01) helloHibernate

choi jae ho edited this page Mar 5, 2022 · 17 revisions

helloHibernate

Hibernate ์—ฐ์Šต

Benefits of Hibernate

  1. Hiberante provides the Object-to-Relational Mapping(ORM)
  2. Hibernate handles all of the low-level SQL
  • JDBC ์ฝ”๋“œ์˜ ์–‘์„ ์ตœ์†Œํ™” ํ•ด์ค€๋‹ค.

Application Architecture

  • SessionFactory๋ฅผ ์‚ฌ์šฉํ•ด์„œ session์„ ๋งŒ๋“ค์–ด DB์™€ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ํ•œ๋‹ค.
  • hibernate.cfg.xml
  • *.hbm.xml class mappings : ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ” ์‚ฌ์ด์— ๋งคํ•‘์„ ํ•˜๋Š” ๋ถ€๋ถ„

1) Configuration

  • Hibernate Config (์„ค์ •์ •๋ณด) : hibernate.cfg.xml ์„ ์ฝ์Œ
  • Hibernate Mapping (๋งคํ•‘์ •๋ณด) : *.hbm.xml class mappings ์„ ์ฝ์Œ

2) SessionFactory

  • Configuration์—์„œ SessionFactory๋ฅผ ๋งŒ๋“ ๋‹ค. (singleton)
  • SessionFactory์—์„œ Session์„ ๋งŒ๋“ค๊ณ  ์ด ์„ธ์…˜์ด JDBC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Database์— ์ ‘๊ทผ์„ ํ•œ๋‹ค.
  • Transaction๋„ Session์—์„œ ๋งŒ๋“ค์–ด์ค€๋‹ค.

Configuartion Object

SessionFactory Object

Session Object (์„ธ์…˜ ๊ฐ์ฒด)

  • application and database ์‚ฌ์ด์˜ connection ์„ ์–ป๊ธฐ ์œ„ํ•จ.
  • thread safe ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋žซ๋™์•ˆ ์—ด์–ด ๋‘์ง€ ์•Š๋Š”๋‹ค.
  • entity classes ์— ๋Œ€ํ•ด crud ๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค.
  • hibernate์—์„œ cache๋ฅผ ์‚ฌ์šฉ, ํ•œ๊บผ๋ฒˆ์— ๋ชจ์•„์„œ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค. (ํผํฌ๋จผ์Šค์— ์˜ํ–ฅ)

Object states

  • Instances of entity classes may exist in one of the following three states
  1. Transient : ๋ฉ”๋ชจ๋ฆฌ์ƒํƒœ์— ๋‚จ์•„์ ธ์žˆ์Œ
  2. Persistent : ์˜์†์ ์ธ ์ƒํƒœ
  3. Detached : ์„ธ์…˜๊ณผ ๋ถ„๋ฆฌ๋จ

public class HibernateTest {
    public static void main() {

	Person person = new Person();	// Transient Object
	person.setUserName("Test User"); 
		
	SessonFactory sessionFactory = 
		new Configuration().configure().buildSessionFactory();
	Sesson session = SessionFactory.openSession();
	session.beginTransaction();
		
	session.save(person);  // Persistent Object
		
	// Any Changes made to the persistent object get reflected in the DB
	person.setUserName("Updated User");
	person.setUserName("Updated User Again");
		
	session.getTransaction().commit();
	session.close();
		
	// Detached Object; hibernate is not going to track the changes
	person.setUserName("Updated User After session close");		
    }
}

(1) Hibernate-introduction

Ex. Spring ์—†์ด Java Application์„ ์ด์šฉํ•ด์„œ Hibernate ์‚ฌ์šฉ

pom.xml

์˜์กด์„ฑ ์ถ”๊ฐ€

  1. Hibernate-core
  2. MySQL Connector
  3. lombok
  4. logback

		<!-- Hibernate Dependency ์ถ”๊ฐ€. -->
		<!-- Hibernate-core -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.4.29.Final</version>
		</dependency>
		<!-- MySQL Connector -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.20</version>
		</dependency>

		<!-- lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.12</version>
			<scope>provided</scope>
		</dependency>

		<!-- logback -->
		<!-- logback-classic๋งŒ ๋„ฃ์–ด์ฃผ๋ฉด, core๋„ ๋“ค์–ด๊ฐ -->
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
			<scope>runtime</scope>
		</dependency>

src/main/resources

1. 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/testdb?useSSL=false&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Seoul</property>
		<property name="connection.username">root</property>
		<property name="connection.password">hansung</property>
		
		<!-- Select our SQL dialect ๋ฐฉ์–ธ..-->
		<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
		
		<property name="show_sql">true</property>
		<property name="current_session_context_class">thread</property>
		<property name="hbm2ddl.auto">create</property>	<!-- create ํ…Œ์ด๋ธ”์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด ์ค€๋‹ค.  drop : ์ข…๋ฃŒ๋˜๋ฉด ์‚ญ์ œ  -->
		
		<mapping class="helloHibernate.Product"/>	<!-- mapping ํ•ด์„œ ๋ฐ”๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค.  -->
	</session-factory>
</hibernate-configuration>

2. logback.xml

<?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
    	<!-- console Appender -->
    	<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
    		<encoder>
    			<Pattern>.%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %n
    			</Pattern>
    		</encoder>
    		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    			<level>TRACE</level>
    		</filter>
    	</appender>
    
    	<logger name="kr.ac.hansung.cse">
    	    <level value="DEBUG" />
    	</logger>
    	
    	<!-- org.hibernate์— ๋Œ€ํ•ด์„œ ์ž์„ธํžˆ ๋ณด๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€. -->
    	<logger name="org.hibernate.type.descriptor.sql">
    	    <level value="Trace" />
    	</logger>
    	
    	<root>
    		<level value="INFO" />
    		<appender-ref ref="consoleAppender" />
    	</root>
    </configuration>

src/main/java

3. Product.java

package helloHibernate;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/*
 * Entity class : Java class that is mapped to a database table
 * 
 * Java Annotations 
 * - map class to database table
 * - map fields to database columns
 * 
 */

@Getter
@Setter
@ToString
@Entity
@Table(name="product")
public class Product {
	
	@Id							//id๋กœ ์‚ฌ์šฉ. primary key
	@GeneratedValue						//ํ‚ค๋ฅผ ์ƒ์„ฑํ• ๋•Œ๋Š”, ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค. 
	@Column(name="product_id")				//์ปฌ๋Ÿผ ๋‚ด์šฉ์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.  - ๋งŒ์•ฝ์— name์„ ์ง€์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, field์ด๋ฆ„๊ณผ ๊ฐ™์•„ ์ง„๋‹ค. 
	private int id;
	
	private String name;
	
	private int price;
	
	private String description;
}

4. TestMain.java

package helloHibernate;



import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

//JAVA Application์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ•. 
public class TestMain {
	
	private static SessionFactory sessionFactory;		//Spring ์—์„œ๋Š” DI 
	
	public static void main(String[] args) {
		
		//์„ธ์…˜ ํŽ™ํ† ๋ฆฌ ์–ป์–ด ์˜ค๋Š” ๊ณผ์ •. 
		/*
		 * Configuration conf = new Configuration(); conf.configure();
		 * 
		 * sessionFactory = conf.buildSessionFactory();					//์„ค์ •ํŒŒ์ผ ๋ช…์‹œ = Default ์ด๋ฆ„ : hibernate.cfg.xml
		 */
		
		sessionFactory = new Configuration().configure().buildSessionFactory();		//chained method 
		
		Product product1 = new Product();
		product1.setName("Notebook");
		product1.setPrice(2000);
		product1.setDescription("Awesome notebook");
		
		Session session = sessionFactory.openSession(); 		//์„ธ์…˜์„ ๋งŒ๋“ ๋‹ค.
		Transaction tx = session.beginTransaction(); 			//ํŠธ๋žœ์ ์…˜ ์‹œ์ž‘
		
		session.save(product1); 					//์ž๋™์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋จ.
		
		tx.commit(); 							//ํŠธ๋žœ์ ์…˜ commit
		session.close();						//์„ธ์…˜์„ ๋‹ซ์Œ.
		sessionFactory.close();						//์„ธ์…˜ ํŒฉํ† ๋ฆฌ ๋‹ซ์Œ. 
		
	}

}

<์‹คํ–‰๊ฒฐ๊ณผ (1) product1 ์ถ”๊ฐ€>

logback์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์–ด๋–ค ๊ฐ’์ด ๋‚˜์™”๋Š”์ง€ console์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ

	<!-- org.hibernate์— ๋Œ€ํ•ด์„œ ์ž์„ธํžˆ ๋ณด๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€. -->
    	<logger name="org.hibernate.type.descriptor.sql">
    	    <level value="Trace" />
    	</logger>

console02

MySQL workbench | testdb ํ™•์ธ

์บก์ฒ˜

<์‹คํ–‰๊ฒฐ๊ณผ (2) product1, product2 ์ถ”๊ฐ€ , createQuery() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ>

TestMain.java ๋ณ€๊ฒฝ

package helloHibernate;



import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

//JAVA Application์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ•. 
public class TestMain {
	
	private static SessionFactory sessionFactory;		//Spring ์—์„œ๋Š” DI 
	
	public static void main(String[] args) {
		
		//์„ธ์…˜ ํŽ™ํ† ๋ฆฌ ์–ป์–ด ์˜ค๋Š” ๊ณผ์ •. 
		/*
		 * Configuration conf = new Configuration(); conf.configure();
		 * 
		 * sessionFactory = conf.buildSessionFactory();					//์„ค์ •ํŒŒ์ผ ๋ช…์‹œ = Default ์ด๋ฆ„ : hibernate.cfg.xml
		 */
		
		sessionFactory = new Configuration().configure().buildSessionFactory();		//chained method 
		
		Product product1 = new Product();
		product1.setName("Notebook");
		product1.setPrice(2000);
		product1.setDescription("Awesome notebook");
		
		Product product2 = new Product();
		product2.setName("Notebook2");
		product2.setPrice(3000);
		product2.setDescription("Powerful notebook");
		
		Session session = sessionFactory.openSession(); 		//์„ธ์…˜์„ ๋งŒ๋“ ๋‹ค.
		Transaction tx = session.beginTransaction(); 			//ํŠธ๋žœ์ ์…˜ ์‹œ์ž‘
	
		session.save(product1);	
		session.save(product2);	
		
		//๋ฐ”๋กœ DB์— ์ €์žฅ๋˜์ง€ ์•Š์Œ. 
		//์บ์‹œ์— ์ž‡์Œ.
		/*
		 * Serializable id1 = session.save(product1);				//id๋ฅผ ๊ธฐ์–ตํ•จ.
		 * Product savedProduct = session.get(Product.class, id1);
		 * System.out.println("saved product " + savedProduct); //์บ์‹œ์— ์ €์žฅ๋œ๊ฑธ ์ฝ์–ด์˜ด.
		 * session.save(product1);
		 */								
		
		Query<Product> aQuery = session.createQuery("from Product order by name", Product.class);	//HQL ์‚ฌ์šฉ
		List <Product> products = aQuery.getResultList(); //์กฐํšŒ
		System.out.println(products);
		
		tx.commit(); 				//ํŠธ๋žœ์ ์…˜ commit	- ์ด๋•Œ DB์— ์ €์žฅ๋จ. 
		session.close();			//์„ธ์…˜์„ ๋‹ซ์Œ.
		sessionFactory.close();		//์„ธ์…˜ ํŒฉํ† ๋ฆฌ ๋‹ซ์Œ. 
		
	}

}

์ถ”๊ฐ€๋œ ์ •๋ณด๋“ค ์กฐํšŒ
๋ฆฌ์ŠคํŠธ ์กฐํšŒ

MySQL workbench | testdb ํ™•์ธ
22222222

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์„ฑ
reverse


(2)OneToMany - Uni

Category.java ์ถ”๊ฐ€


package helloHibernate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@Entity
@Table(name="category")
public class Category {
	
	@Id
	@GeneratedValue
	@Column(name="category_id")
	private int id;
	
	private String name;
}

Product.java ์ˆ˜์ •


	@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
	@JoinColumn(name="category_id")
	private Category category;

TestMain.java ์ˆ˜์ •


import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

//JAVA Application์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ•. 
public class TestMain {
	private static SessionFactory sessionFactory;		//Spring ์—์„œ๋Š” DI 
	
	public static void main(String[] args) {
		
		//์„ธ์…˜ ํŽ™ํ† ๋ฆฌ ์–ป์–ด ์˜ค๋Š” ๊ณผ์ •. 
		/*
		 * Configuration conf = new Configuration(); conf.configure();
		 * 
		 * sessionFactory = conf.buildSessionFactory();					//์„ค์ •ํŒŒ์ผ ๋ช…์‹œ = Default ์ด๋ฆ„ : hibernate.cfg.xml
		 */
		
		sessionFactory = new Configuration().configure().buildSessionFactory();		//chained method 
		
		Category category1 = new Category();
		category1.setName("์ปดํ“จํ„ฐ");
		
		Category category2 = new Category();
		category2.setName("์ž๋™์ฐจ");
		
		Product product1 = new Product();
		product1.setName("Notebook1");
		product1.setPrice(2000);
		product1.setDescription("Awesome notebook");
		product1.setCategory(category1);
		
		Product product2 = new Product();
		product2.setName("Notebook2");
		product2.setPrice(3000);
		product2.setDescription("Powerful notebook");
		product2.setCategory(category1);
		
		Product product3 = new Product();
		product3.setName("Sonata");
		product3.setPrice(100000);
		product3.setDescription("Popular Car");
		product3.setCategory(category2);
		
		Session session = sessionFactory.openSession(); 		//์„ธ์…˜์„ ๋งŒ๋“ ๋‹ค.
		Transaction tx = session.beginTransaction(); 			//ํŠธ๋žœ์ ์…˜ ์‹œ์ž‘
	
		session.save(product1);	
		session.save(product2);	
		session.save(product3);	
		
		product1.setCategory(null);
		session.delete(product1);
		//๋ฐ”๋กœ DB์— ์ €์žฅ๋˜์ง€ ์•Š์Œ. 
		//์บ์‹œ์— ์ž‡์Œ.
		/*
		 * Serializable id1 = session.save(product1);				//id๋ฅผ ๊ธฐ์–ตํ•จ.
		 * Product savedProduct = session.get(Product.class, id1);
		 * System.out.println("saved product " + savedProduct); //์บ์‹œ์— ์ €์žฅ๋œ๊ฑธ ์ฝ์–ด์˜ด.
		 * session.save(product1);
		 */								
		
		/*
		 * Query<Product> aQuery = session.createQuery("from Product order by name",
		 * Product.class); //HQL ์‚ฌ์šฉ List <Product> products = aQuery.getResultList();
		 * //์กฐํšŒ System.out.println(products);
		 */
		
		tx.commit(); 				//ํŠธ๋žœ์ ์…˜ commit	- ์ด๋•Œ DB์— ์ €์žฅ๋จ. 
		session.close();			//์„ธ์…˜์„ ๋‹ซ์Œ.
		sessionFactory.close();		//์„ธ์…˜ ํŒฉํ† ๋ฆฌ ๋‹ซ์Œ. 
	}

}

hibernate.cfg.xml , mapping class ์ถ”๊ฐ€

	<mapping class="helloHibernate.Category"/>

<ํ…Œ์ด๋ธ”>

2 ๊ฒฐ๊ณผ