Spring Hibernate – Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

Spring Hibernate – Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

1. Giới thiệu Spring ORM

Spring cung cấp API giúp lập trình viên dễ dàng tích hợp Spring với ORM Framework như JPA(Java Persistence API), JDO(Java Data Objects), Oracle Toplink and iBATIS.

Lợi ích của ORM Framework với Spring

Có khá nhiều lợi ích khi kết hợp Spring Framework với ORM framework:

  • Viết code ít hơn: Không cần phải viết code trước và sau khi truy vấn với database qua connection (ví dụ start connection, start transaction, commit transaction, close connection…)
  • Dễ test hơn:
  • Xử lý exception tốt hơn: Spring framewrok cung cấp các API để xử lý exception với ORM framework
  • Tích hợp quản lý transaction: Spring hỗ trợ khả năng quản lý transaction qua AOP (Xem lại ví dụ xử lý transaction với JDBC)

2. Tích hợp Spring Framework với Hibernate Framework

Hibernate là 1 framework thực hiện cài đặt lại JPA

Trong hibernate, chúng ta khai báo thông tin của database trong file hibernate.cfg.xml.

Nếu tích hợp Hibernate với Spring thì chúng ta không cần tạo file hibernate.cfg.xml, chúng ta có thể cung cấp tất cả thông tin trong file spring config.

Việc tích hợp Hibernate với Spring còn giúp chúng ta bớt được rất nhiều code, và không cần phải làm nhiều bước như tạo Configuration, BuildSessionfactory, Session, tạo và commit Transaction…

3. Code ví dụ Spring Hibernate

Ở ví dụ này mình sử dụng:

Tạo database:

CREATE SCHEMA `demo-spring-hibernate` ;
CREATE TABLE `demo-spring-hibernate`.`customer` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `address` VARCHAR(255) NULL,
  PRIMARY KEY (`id`));

Spring Hibernate - Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

Tạo maven project:

Spring Hibernate - Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

Thư viện sử dụng:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>stackjava.com</groupId>
  <artifactId>DemoJDBC</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
    <!-- Spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

    <!-- Hibernate -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.12.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>5.2.12.Final</version>
    </dependency>
    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.4</version>
    </dependency>

    <!-- MySQL -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.45</version>
    </dependency>

  </dependencies>
</project>

File Spring config:

<?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:tx="http://www.springframework.org/schema/tx"
  xmlns:context="http://www.springframework.org/schema/context"
  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">

  <context:annotation-config />
  <context:component-scan base-package="stackjava.com.springhibernate" />
  

  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url"
      value="jdbc:mysql://localhost:3306/demo-spring-hibernate" />
    <property name="username" value="root" />
    <property name="password" value="admin1234" />
  </bean>
  
  <bean id="sessionFactory"
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    
    <property name="packagesToScan" value="stackjava.com.springhibernate.entities" />
    <!-- <property name="annotatedClasses">
      <list>
        <value>stackjava.com.springhibernate.entities.Customer</value>
      </list>
    </property> -->
    
    
    <property name="hibernateProperties" value="classpath:hibernate.properties" />
    <!-- <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.current_session_context_class">thread</prop>
        <prop key="hibernate.show_sql">false</prop>
      </props>
    </property> -->
    
  </bean>

</beans>
  • org.apache.commons.dbcp.BasicDataSourcechứa các thông tin kết nối tới database
  • org.springframework.orm.hibernate5.LocalSessionFactoryBean: tạo đối tượng sessionFactory.
    • Thuộc tính packagesToScan sẽ chỉ định package chứa các file entity map với table trong database (hoặc bạn cũng có thể chỉ rõ các class entity mapping với table bằng thuộc tính annotatedClasses)
    • Thuộc tính hibernateProperties khai báo file chưa các thông tin config hibernate (hoặc bạn cũng có thể chỉ rõ các thông tin config trong file spring config luôn)

 File Hibernate config:

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hibernate.current_session_context_class=thread
hibernate.show_sql=true

File entity:

package stackjava.com.springhibernate.entities;

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

@Entity
@Table(name = "customer")
public class Customer {
  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "name")
  private String name;

  @Column(name = "address")
  private String address;

  public Customer() {
  }

  public Customer(int id, String name, String address) {
    this.id = id;
    this.name = name;
    this.address = address;
  }

  public Customer(String name, String address) {
    this.name = name;
    this.address = address;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getAddress() {
    return address;
  }

  public void setAddress(String address) {
    this.address = address;
  }

}

File DAO:

package stackjava.com.springhibernate.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import stackjava.com.springhibernate.entities.Customer;

@Repository(value = "customerDAO")
public class CustomerDAO {
  
  @Autowired
  private SessionFactory sessionFactory;

  public void save(Customer customer) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.persist(customer);
    tx.commit();
    session.close();
  }
  
  public void update(Customer customer) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.update(customer);
    tx.commit();
    session.close();
  }
  
  public List<Customer> findAll() {
    Session session = this.sessionFactory.openSession();
    List<Customer> result = session.createQuery("FROM Customer", Customer.class).getResultList();
    return result;
  }
  
  public Customer findById(int id) {
    Session session = this.sessionFactory.openSession();
    return session.find(Customer.class, id);
  }

  public void delete(Customer customer) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.delete(customer);
    tx.commit();
    session.close();
  }

}

Demo:

package stackjava.com.springhibernate.main;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import stackjava.com.springhibernate.dao.CustomerDAO;
import stackjava.com.springhibernate.entities.Customer;

public class MainApp {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    CustomerDAO customerDAO = (CustomerDAO) context.getBean("customerDAO");
    
    customerDAO.save(new Customer("Rooney", "Manchester"));
    customerDAO.save(new Customer("Gerrard", "Liverpool"));
    
    List<Customer> listCustomer = customerDAO.findAll();
    for (Customer customer : listCustomer) {
      System.out.println(customer.getId() + " - " + customer.getName() + " - " + customer.getAddress());
    }
//		
//		Customer customer = new Customer(1, "Gerrard", "Liverpool");
//		customerDAO.update(customer);
    context.close();
  }
}

Kết quả:

Spring Hibernate - Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

Spring Hibernate - Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

Okay, Done!

Phần tiếp theo chúng ta sẽ tìm hiểu và áp dụng AOP vào quản lý transaction với Spring Hibernate.

Download code ví dụ trên tại đây

Thanks all!

 

Spring Hibernate – Giới thiệu Spring ORM, Code ví dụ Spring Hibernate

References:

https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html

https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch14s02.html

stackjava.com