Cài đặt và sử dụng Hibernate – GP Coder (Lập trình Java)

Trong các bài viết trước chúng ta đã cùng tìm hiểu các khái niệm về JPA và Hibernate. Trong bài này, chúng ta sẽ cùng tìm hiểu cách cài đặt và sử dụng Hibernate.

Để sử dụng Hibernate, chúng ta sẽ lần lượt thực hiện các bước sau:

  • Tạo maven project.
  • Khai báo thư viện Hibernate và thư viện JDBC ứng với loại database cần sử dụng.
  • Tạo các Entity và các mapping.
  • Tạo file cấu hình Hibernate.
  • Tạo đối tượng SessionFactory
  • Sử dụng SessionFactory để thực hiện các câu lệnh truy vấn đến database.

Cài đặt Hibernate

Tạo maven project và trong file pom.xml khai báo thư viện Hibernate 5, và thư viện JDBC tương ứng cho các loại Database khác nhau MySQL, PostgreSQL, Oracle, SQL Server, …

Trong bài này, tôi sẽ sử dụng database MySQL. Nội dung file pom.xml như sau:


<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>com.gpcoder</groupId>
	<artifactId>HibernateTutorial</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>HibernateTutorial</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
	</properties>

	<dependencies>

		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.10</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.4.7.Final</version>
		</dependency>

		<!-- MySQL -->
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.17</version>
		</dependency>

		<!-- Unit Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

Tạo các Entity và các mapping

Tiếp theo chúng ta sẽ tạo các Enity. Mỗi Entity sẽ đại diện cho một bảng trong database.

Giả sử tôi có một table user với cấu trúc như sau:


CREATE TABLE `user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`fullname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`modified_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Chúng ta sẽ sử dụng các Annotation để ánh xạ (mapping) classproperty trong Java tương ứng với các tablecolumn trong database.

User.java


package com.gpcoder.entities;

import java.util.Date;

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

import lombok.Data;

@Data
@Entity
@Table(name = "user")
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column
	private String fullname;

	@Column
	private String username;

	@Column
	private String password;

	@Column(name = "created_at")
	private Date createdAt;

	@Column(name = "modified_at")
	private Date modifiedAt;
}

Một số Annotation được sử dụng:

  • @Entity : cho biết đây là một Entity.
  • @Table : cho biết đây là một Table trong database, chúng ta có thể chỉ định tên tương ứng và các ràng buộc trong database. Mặc định, Hibernate sẽ lấy tên class tương ứng với tên table trong database nếu nó không được chỉ định name.
  • @Id : đây là Identity của Entity. nó tương đương với khóa chính (Primary key) của table.
  • @GeneratedValue : được sử dụng để Hibernate tự động tạo ra giá trị và gán vào cho một cột trong trường hợp insert mới một Entity vào database.
  • @Column : được sử dụng để chú thích đây là một column trong database. Nó có thể bao gồm các thông tin ràng buộc của column như độ dài của cột, cho phép null hay không, … Mặc định, Hibernate sẽ lấy tên property tương ứng với tên column trong database nếu nó không được chỉ định name.

Chúng ta sẽ tìm hiểu chi tiết về các Annotation của Hibernate ở một bài viết khác.

Tạo file cấu hình Hibernate

Để làm việc với Hibernate, chúng ta cần phải có một file cấu hình. Trong file này, chúng ta sẽ khai báo loại database mà chúng ta sẽ sử dụng, những thông tin cần thiết để Hibernate có thể kết nối đến database đó và những Java object mà chúng ta đã ánh xạ từ java object (entity) với các table trong database.

Tạo file hibernate.cfg.xml  và đặt nó trong thư mục src\main\resources

Nội dung file này như sau:


<?xml version='1.0' encoding='utf-8'?>
<!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>
		<!-- Database setting -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/gp_system?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8</property>
		<property name="connection.username">root</property>
		<property name="connection.password"></property>
		
		<!-- JDBC connection pool (use the built-in) -->
		<property name="connection.pool_size">4</property>

		<!-- SQL dialect -->
		<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

		<!-- Enable Hibernate's automatic session context management -->
		<property name="current_session_context_class">thread</property>

		<!-- Disable the second-level cache -->
		<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

		<!-- Show all executed SQL to console -->
		<property name="show_sql">true</property>

		<!-- Entity mapping -->
		<mapping class="com.gpcoder.entities.User" />
		
	</session-factory>
</hibernate-configuration>

Tạo đối tượng SessionFactory

Như đã giới thiệu ở bài viết trước, SessionFactory là một interface giúp tạo ra session kết nối đến database bằng cách đọc các cấu hình trong Hibernate configuration.

SessionFactory là đối tượng nặng (heavy weight object) và được sử dụng thường xuyên nên chúng ta sẽ tạo một class singleton HibernateUtils để sử dụng sau này.

HibernateUtils.java


package com.gpcoder.utils;

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtils {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private HibernateUtils() {
		super();
	}

	private static SessionFactory buildSessionFactory() {
		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() //
				.configure() // Load hibernate.cfg.xml from resource folder by default
				.build();
		Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();
		return metadata.getSessionFactoryBuilder().build();
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public static void close() {
		getSessionFactory().close();
	}
}

Sử dụng SessionFactory để thực hiện các câu lệnh truy vấn đến database

Chúng ta đã chuẩn bị đầy đủ mọi thứ, công việc bây giờ là sử dụng thôi.

Đầu tiên, chúng ta cần mở một session để làm việc với Hibernate:


Session session = HibernateUtils.getSessionFactory().openSession();

Để bắt đầu làm việc, chúng ta sẽ mở một Transaction mới:


session.beginTransaction();

Truy vấn database: Hibernate hỗ trợ nhiều cách để truy vấn database, trong bài này chúng ta sẽ sử dụng HQL để truy vấn database. HQL có một chút khác biệt với SQL:

  • SQL: Truy vấn dữ liệu trên các table và column.
  • HQL: Truy vấn dữ liệu trên các entity và property.

Sau khi đã sử dụng xong, chúng ta cần gọi commit() để lưu mọi thay đổi xuống database.


session.getTransaction().commit();

Ví dụ bên dưới sẽ thực hiện các thao tác: Insert, Update, Delete, Count, Select dữ liệu của database.


package com.gpcoder;

import java.util.Date;
import java.util.List;

import org.hibernate.Session;

import com.gpcoder.entities.User;
import com.gpcoder.utils.HibernateUtils;

public class HibernateExample1 {
	
	public static void main(String[] args) {
		
		try (Session session = HibernateUtils.getSessionFactory().openSession();) {
			// Begin a unit of work
			session.beginTransaction();

			// Insert user
			Date currentDate = new Date();
			User user1 = new User();
			user1.setFullname("Hibernate Example");
			user1.setUsername("gpcoder");
			user1.setPassword("123456"); // Should encode password
			user1.setCreatedAt(currentDate);
			user1.setModifiedAt(currentDate);
			Long userId = (Long) session.save(user1);
			System.out.println("User id = " + userId); 
			
			// Count user from database
			Long numberOfUser = session.createQuery("SELECT COUNT(id) FROM User", Long.class).uniqueResult();
			System.out.println("Number of user in database: " + numberOfUser);
			
			// Get user by id
			User savedUser = session.find(User.class, userId);
			System.out.println("savedUser: " + savedUser);
			
			// Update user
			savedUser.setFullname("GP Coder");
			session.update(savedUser);

			// Get users
			List<User> users = session.createQuery("FROM User", User.class).list();
			users.forEach(System.out::println);
			
			// Delete user
			session.delete(savedUser);
			
			// Count user from database
			numberOfUser = session.createQuery("SELECT COUNT(id) FROM User", Long.class).uniqueResult();
			System.out.println("Number of user in database: " + numberOfUser);
			
			// Commit the current resource transaction, writing any unflushed changes to the database.
			session.getTransaction().commit();
		}
	}
}

Một số phương thức được sử dụng:

  • save() : insert một entity vào database. Phương thức này trả về id của record đã được save.
  • update() : cập nhật entity vào database.
  • delete() : xóa entity khỏi database.
  • createQuery() : tạo câu lệnh query đến database.
  • find() : tìm entity dựa vào id được cung cấp.

Chạy chương trình trên, chúng ta có kết quả như sau:


Hibernate: insert into user (created_at, fullname, modified_at, password, username) values (?, ?, ?, ?, ?)
User id = 1
Hibernate: select count(user0_.id) as col_0_0_ from user user0_
Number of user in database: 1
savedUser: User(id=1, fullname=Hibernate Example, username=gpcoder, password=123456, createdAt=Sat Oct 26 00:04:47 ICT 2019, modifiedAt=Sat Oct 26 00:04:47 ICT 2019)
Hibernate: update user set created_at=?, fullname=?, modified_at=?, password=?, username=? where id=?
Hibernate: select user0_.id as id1_0_, user0_.created_at as created_2_0_, user0_.fullname as fullname3_0_, user0_.modified_at as modified4_0_, user0_.password as password5_0_, user0_.username as username6_0_ from user user0_
User(id=1, fullname=GP Coder, username=gpcoder, password=123456, createdAt=Sat Oct 26 00:04:47 ICT 2019, modifiedAt=Sat Oct 26 00:04:47 ICT 2019)
Hibernate: delete from user where id=?
Hibernate: select count(user0_.id) as col_0_0_ from user user0_
Number of user in database: 0

Như các bạn thấy, sử dụng Hibernate việc truy vấn database đơn giản hơn rất nhiều so với sử dụng JDBC API.

Tài liệu tham khảo:

5.0

Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé!

Shares

Bình luận

bình luận