Hibernate
1.ORM(Object Relation Mapper)
- 하나의 테이블과 클래스를 매핑하는 방식의 데이터베이스 프레임워크로 하나의 행을 하나의 인스턴스로 표현
- SQL을 이용하기도 하고 SQL 없이도 데이터베이스 작업이 가능
- 기본키를 가지고 하는 작업은 아주 쉽게 처리할 수 있다.
- Java의 ORM 표준 spec을 JPA라고 이에 대하나 구현체가 Hibernate
- 현재는 대다수의 프로그래밍 언어들에 ORM 프레임워크가 구현되어 있다.
2.Hibernate의 장점
- 복잡한 JDBC 코드를 제거
- Spring 과의 통합 기능 제공
- 성능이 MyBatis 보다 우수 : 카카오나 배달의 민족이 Hibernate로 구현
3.단점
- 초기 설정이 MyBatis에 비해서 어려움
- SI 업계에서는 MyBatis를 선택하고 솔루션 업계에서는 Hibernate
4.자료형 매핑
integer(number)
<->int, java.lang.Intger
long(number)
<->long, java.langLong
double(number)
<->double, java.lang.double
boolen, yes/no, true/false
<->boolean, java.lang.Boolean
date
<->java.sql.Date, java.util.Date
time
<->java.sql.Time, java.util.Date
timestamp
<->java.sql.Timestamp, java.util.Date
char, varchar(varchar2 - Oracle), string, clob - Oracle, text
<->java.lang.String
blob(파일의 내용 - 바이트 배열)
<->java.sql.Blob
5. 하이버네이트 Mapper 만들기 - xml 파일
<hibernate-mapping package="테이블과 매핑할 클래스 경로">
<class name="클래스이름" table="테이블이름">
<id name="변수이름" column="컬럼이름"></id> //기본키 설정
<property name="변수이름" column="컬럼이름"/>
... 프로퍼티 추가
</class>
</hibernate-mapping>
6.하이버네이트 bean 생성
1) PersistencyExceptionTransactionPostProcessor 클래스의 bean 생성
2) LocalSessionFactoryBean 클래스의 bean을 생성
- DataSource, 하이버네이트 매퍼 파일, 데이터베이스 종류가 필요
3) HibernateTransactionManager 클래스의 bean 생성 - 2번의 bean이 필요
7.하이버네이트 bean 객체 사용
- SessionFactory 클래스의 bean을 주입받아서 사용
- getCurrectSession()을 호출하고 필요한 메소드를 호출
8.의존성 라이브러리
- spring-orm, hibernate
실습. Goods 테이블의 CRUD 작업을 Hibernate를 이용해서 처리
- 1, 2번까지는 설정, 3번부터 실제 시작
1.Project 를 생성
2.pom.xml 파일에 Hibernate 사용을 위한 의존성을 설정
- oracle, sping-jdbc, spring-orm, hibernate
3.테이블 과 매핑할 DTO 클래스를 생성
- db.hibernate.domain.Good
package db.hibernate.domain;
import lombok.Data;
@Data // lombok
public class Good {
// 테이블과의 이름은 안맞춰도 되고, 자료형은 맞춰야됨니다.
private int code1 ;
private String name1;
private String manufacture1;
private int price1;
}
4. DTO 클래스와 연동할 테이블을 매핑하는 매핑 파일을 생성
- db.hibernate.dao 패키지에 good.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package : DTO 클래스의 패키지 이름 -->
<hibernate-mapping package="db.hibernate.domain">
<!-- property 구문 : 테이블에서의 column 이 한글일 때가 있다. -->
<!-- property 구문 : name은 DTO 클래스의 변수 -->
<!-- 테이블이름은 대소문자 구분X, 값만구분 -->
<class name="Good" table="goods">
<id name="code1" column="code"></id>
<property name="name1" column="name"/>
<property name="manufacture1" column="manufacture"/>
<property name="price1" column="price"/>
</class>
</hibernate-mapping>
5. src/main/resources 디렉토리에 Spring Bean Configuration 파일을 추가
- hibernateContext.xml
- DataSource, Hibernate 관련 Bean
1) context , tx 네임스페이스 추가
2) 코드 추가
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 어노테이션을 이용한 bean 생성을 위한 설정 -->
<context:annotation-config/>
<!-- 자동으로 bean을 생성할 패키지를 위한 설정 -->
<context:component-scan base-package="db"/>
<!-- 트랜잭션을 어노테이션을 이용해서 사용할 수 있도록 해주는 설정 -->
<tx:annotation-driven/>
<!-- DataSource -->
<!-- 스프링에서 데이터베이스를 사용할 때 접속 정보를 저장할 bean -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<!-- 데이터 베이스 종류 -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!-- 데이터베이스 위치 : 데이터베이스 종류마다 작성법 다름 (검색필요) -->
<property name="url" value="jdbc:oracle:thin:@211.183.6.60:1521:xe"/>
<!-- 계정과 비밀번호 -->
<property name="username" value="user13" />
<property name="password" value="user13" />
</bean>
<!-- 하이버네이트 연동 Bean 생성 -->
<bean class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource"/>
<!-- 하이버네이트 설정 파일 등록 -->
<!-- 설정 파일이 여러개이면 value를 추가 -->
<property name="mappingResources">
<list>
<value>
db/hibernate/dao/good.hbm.xml <!-- 경로 -->
</value>
</list>
</property>
<!-- 사용할 데이터베이스 종류 설정 -->
<!-- 데이터베이스 종류 별로 고정된 값 -->
<property name="hibernateProperties">
<value>
hibernate.dialect = org.hibernate.dialect.Oracle10gDialect
</value>
</property>
</bean>
<!-- 하이버네이트 트랜잭션 사용 bean -->
<bean class="org.springframework.orm.hibernate5.HibernateTransactionManager" id="transactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>
</beans>
6. Dao 클래스를 만들어서 데이터를 삽입하는 메소드 구현
- db.hibernate.dao.GoodDao
package db.hibernate.dao;
import javax.transaction.Transactional;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import db.hibernate.domain.Good;
// bean 생성을 자동으로 해주는 어노테이션
@Repository
public class GoodDao {
// 하이버네트 사용 변수 생성
@Autowired
private SessionFactory sessionFactory;
// 데이터 삽입하는 메소드
@Transactional
public int insertGood(Good good) {
sessionFactory.getCurrentSession().save(good);
// save, insert, update, delete
return 1; // 삽입 성공 1, 실패 0
}
}
7.main 메소드를 소유한 hibernateMain 클래스 작성
package db.hibernate.main;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.hibernate.dao.GoodDao;
import db.hibernate.domain.Good;
public class HibernateMain {
public static void main(String[] args) {
GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:hibernateContext.xml");
GoodDao dao = context.getBean(GoodDao.class);
Good good = new Good();
good.setCode1(200);
good.setName1("자동차");
good.setManufacture1("군산");
good.setPrice1(30000000);
dao.insertGood(good);
context.close();
}
}
8.실행하고 데이터베이스 확인
테이블과 매핑할 DTO 클래스 만듬
lombok 이용 @Data로 DTO 클래스 만들었음
good.hbm.xml 만듬
db.hiberante.dao Package
패키지 이름, 클래스이름, 테이블이름, DTO 변수명
sping bean 파일 만듬
hibeerContext.xml
bean 설정
9.데이터 수정 기능 구현 - 기본키를 가지고 조회해서 나머지 데이터 변경
1) Dao 클래스에 메소드를 추가
// 데이터 수정하는 메소드
@Transactional
public void updateGood(Good good) {
sessionFactory.getCurrentSession().update(good);
}
2) main 메소드 수정하고 테스트
GoodDao dao = context.getBean(GoodDao.class);
Good good = new Good();
good.setCode1(100);
good.setName1("자동차");
good.setManufacture1("군산");
good.setPrice1(300000);
dao.updateGood(good);
10.삭제기능 구현
1) Dao 클래스에 메소드 구현
// 데이터 삭제하는 메소드
@Transactional
public void deleteGood(Good good) {
sessionFactory.getCurrentSession().delete(good);
}
2) main 메소드 수정하고 테스트
Good good = new Good();
good.setCode1(100);
dao.deleteGood(good);
hibernate는 대규모 프로젝트에 쓰지 못한다.
폭포수 모델 : 혼자하기는 어렵다
분석 -> 설계 -> DB구축 -> 개발(코딩) <-> 테스트 -> 배포(유지보수)분석 - 고객voice를 Computer에 넣을 수 있는지,기술영업, 현직 개발 했던 사람이
설계 - 자기들만의 용어를 씀, 개발 vs 설계 말이 안통해 , 현직vs교수 말이 안통해
개발, DB구축 - MyBatis 를 많이 쓴다. Hibernate는 DB, 개발 서로 어렵다 (잘구축해야하기때문에)Micro Service - 작은 분류로 나눠서 업무분담. 단위 서비스
테이블에서 데이터를 가져올 때 생각해봐야할 점. 행의 구조인지, 열의 구조인지
하나의 값인지, 모두의 값인지
기본형, String, Data,하나의 행 여러개 값
java - Map, DTO클래스
python - dict, tuple, DTO클래스여러개 열, 여러개 행
List<DTO>
,List<Map>
11.테이블의 데이터 전체를 가져오는 메소드
1) Dao 클래스에 메소드를
// 테이블의 데이터를 전부 가져오는 메소드
@Transactional
public List<Good> allGood() {
// Good 클래스와 연결된 테이블의 모든 데이터 찾아오기
return sessionFactory.getCurrentSession().createCriteria(Good.class).list();
}
// code를 가지고 하나의 행을 찾아오는 메소드
@Transactional
public Good getGood(int code) {
return sessionFactory.getCurrentSession().get(Good.class, code);
}
@Transactional
public List<Good> allGood() {
// Good 클래스와 연결된 테이블의 모든 데이터 찾아오기
// SQL을 이용해서 데이터 가져오기
// 메소드의 리턴 값을 가지고 다른 메소드를 호출 하는 것을 - 메소드 체이닝
// 변수를 만들지 않고 메소드 호출을 처리하기 위해서 사용
return sessionFactory.getCurrentSession().createSQLQuery("selet * from goods").addEntity(Good.class).getResultList();
}
2) main 메소드 수정
package db.hibernate.main;
import java.util.List;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.hibernate.dao.GoodDao;
import db.hibernate.domain.Good;
public class HibernateMain {
public static void main(String[] args) {
GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:hibernateContext.xml");
GoodDao dao = context.getBean(GoodDao.class);
/*
List<Good> list = dao.allGood(); for(Good good : list) {
System.err.println(good); }
*/
Good good = dao.getGood(2);
System.err.println(good);
context.close();
}
}