※ Hibernate 적용 전 상식!
- Spring MVC 프로젝트 구조
- 각각 패키지 안에 있는 클래스에 쓰는 annotation
: @Controller @Repository @ Entity @ Service
- 클래스들은 classes 폴더에. war 파일로 패키징 돼서 디플로이 된다.
★ Integrating Hibernate with the Spring Framework
1. Maven Dependencies
: Spring - spring-orm , Hibernate - hibernate-core
<!– Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!– Hibernate ->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.12.Final</version>
</dependency>
2. Hibernate configuration (dao-context.xml)
- configuring DataSource Bean
<context:property-placeholder location="/WEB-INF/props/jdbc.properties" />
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="DAO 페키지명">
</context:component-scan>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
- dao 클래스는 내가 만든 Source이므로 annotation만 사용하면 dao 클래스라는 것을 Spring이 알 수 있다.
- BasicDataSource는 라이브러리에 들어있는 소스코드 이므로 xml을 사용해서 빈으로 등록하는 것
(굳이 소스에 들어가 보지 않아도 되기 때문에)
- Configuring SessionFactory Bean
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan">
<list>
<value>Model 페키지명</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
</bean>
- LocalSessionFacotryBean
- dataSource: 액세스 할 데이터 소스
(ref에 들어가는 값은 앞에서 등록한 빈(dataSource) id와 같아야 된다.) - packagesToScan: Hibernate가 지정된 패키지 아래에 있는 ORM annotation이 붙은 도메인 객체를 스캔한다.
- dataSource: 액세스 할 데이터 소스
- hibernateProperties
- Hibernate에 대한 구성 세부사항 설정
- hbm2ddl.auto: Hibernate가 실행될 때마다 매핑 설정을 DB 스키마에 적용
- create:
- SessionFacotry가 실행될 때마다 스키마를 지웠다가 다시 생성 -> data가 다 날아감(개발할 때 사용) - create-drop:
- SessionFactory가 내려갈 때마다 스키마를 지웠다가 다시 생성 - update:
- 도메인 객체 구성과 스키마를 비교해 필요한 테이블이나 칼럼을 객체에 맞춰서 스키마를 변경한다.
-> data 쌓임! - validate:
- 도메인 객체와 스키마가 같은 지 확인하고 다르면 예외로 빠진다.
- create:
- show_sql: 말 그대로 hibernate가 만들어내는 sql를 볼 것이냐
- format_sql: 여러 줄로 포맷해서 이쁘게 볼 것이냐를 설정.
- true: 이쁘게 포맷!
- false: 한 줄로 쭉 나온다.
※ hibernateProerties를 설정하고 나서 id가 sessionFactory라는 빈을 등록!
- Configuring TransactionManger Bean
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
- HibernateTransationManager: 트랜잭션 관리
- transaction은 begin으로 시작하고 commit으로 끝난다.
- Spring은 AOP를 (before advice(begin) after advice(commit)) 사용
- @Transactional을 클래스 레벨에 적용했기 때문에 그 밑에 있는 메서드에 전부 적용된다.
-> before, after advice 자동 삽입 - 클래스 앞부분에 springframework가 붙어있으면 springframe에서 지원해주는 클래스
3. Mapping Model Class using Annotations
- Object Tier vs Database element
Object Tier element | Database Tier element |
Entity class | Database table |
Field of entity class | Database table column |
Entity instance | Database table row |
- JPA (Java Persistence API)
: 일종의 spec(API를 이런 식으로 구현하면 좋겠다) -> Hiberante는 JPA를 실제 구현한 것.
- JPA Annotation
- @Entity:
- Entity bean을 선언
(Entity bean이란? hibernate에 의해서 DB에 저장될 수 있는 bean) - @Table:
- 기본적으로 테이블 명은 클래스명으로 가져가지만 이 Annotation으로 오버 라이딩해줄 수 있다. - @Id
- primary key를 설정하는 Annotation - @GeneratedValue
- key를 자동 생성하는 Annotation, 디폴트 값은 Auto
- Auto 설정: mysql에서 hibernate 4는 IDENTITY로 hibernate 5에서는 Table로 만들어짐
( IDENTITY: 자동 증가 db column을 사용한다는 뜻 )
( table로 만들어진다는 의미: db에 primary key를 만들기 위해 테이블을 사용한다는 뜻
-> hibernate_sequence라는 테이블 ) - @Column
- 속성을 table column과 맵핑하는 데 사용.
- Bean property에 길이, NULL 입력 가능 및 uniqueness를 지정 가능.
- @Entity:
- 예시 코드
@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="product_id")
private int id;
private String name;
private String category;
private double price;
private String manufacturer;
private int unitInStock;
private String description;
@Transient
private MultipartFile productImage;
private String imageFilename;
}
- @Transient(persistence와 반대말)
- 저장하지 않을 필드에 적용하는 annotation
- 언제 사용되나...
-> 동영상이나 이미지는 db에 저장하지 않는다(File Server에 저장)
-> db에는 filename만 저장 (경로만 저장)
-> 따라서 이미지 자체는 저장하지 않으므로 이 annotation을 사용
4. DAO
- 이전에 사용했던 JDBC는 이제 필요 x, Hibernate로 대체!!
- CRUD 구현
@Repository
@Transactional
public class ProductDao {
@Autowired
private SessionFactory sessionFactory;
public Product getProductById(int id) {
Session session = sessionFactory.getCurrentSession();
Product product = (Product) session.get(Product.class, id);
return product;
}
@SuppressWarnings("unchecked")
public List<Product> getProducts() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from Product");
List<Product> productList = query.list();
return productList;
}
public void addProduct(Product product) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(product);
session.flush();
}
public void deleteProduct (Product product) {
Session session = sessionFactory.getCurrentSession();
session.delete(product);
session.flush();
}
public void editProduct(Product product) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(product);
session.flush();
}
}
- SessionFactory:
- 앞에서 bean으로 만들어 놨기 때문에 @Autowired로 주입해준다.
(@Autowired는 타입을 보고 주입을 한다.), SessionFactory bean을 싱글톤으로 만들어 놨다. - @SuppressWarnings
- List와 list()는 타입이 다르기 때문에 warning을 내지 마라(중요하지 않음) - flush():
- cache에 있는 값을 db에 반영시키는 것
(자주 flush를 하면 performance에 문제가 있다.)
'Spring > 이론' 카테고리의 다른 글
Restful Web Service with Spring (0) | 2020.04.20 |
---|---|
Restful Web Service (0) | 2020.04.19 |
Entity Relationships (0) | 2020.04.17 |
Hibernate (0) | 2020.04.10 |
Apache Tiles (0) | 2020.04.08 |
댓글