Code ví dụ Hibernate tự sinh ID dạng text, String
(Xem thêm: Hướng dẫn tự học Hibernate)
(Xem thêm: Code ví dụ Hibernate ID tự tăng (@GeneratedValue, @GenericGenerator))
Ở bài trước mình đã thực hiện ví dụ tạo id tự tăng (tự động tạo id) dạng số (Long, Integer). Nhưng với trường hợp id không phải dạng số thì làm thế nào? Ví dụ chúng ta hay bắt gặp id có dạng: EMP001, VNE002, 0001… và nhưng id này cũng tự tăng nhé.
Trong bài này mình sẽ làm code ví dụ thực hiện điều đó.
Các công nghệ sử dụng
Tạo database
Mình tạo 1 database với table employee trong đó column id là primary key dạng text.
CREATE SCHEMA `hibernate-generate-id` ; CREATE TABLE `hibernate-generate-id`.`employee` ( `id` VARCHAR(45) NOT NULL, `name` VARCHAR(45) NULL, PRIMARY KEY (`id`));
Tạo Maven Project
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>HibernateGenCustomId</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <hibernate.version>5.3.6.Final</hibernate.version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> </dependencies> </project>
File cấu hình hibernate – jpa
Chứa thông tin kết nối tới database (url, username, password), liệt kê các entity class được mapping với các table trong database.
Trong ví dụ này mình sử dụng entityManager
nên sẽ khai báo file persistence.xml
nếu các bạn sử dụng hibernateSession
thì có thể khai báo file hibernate.cfg.xml
(Xem lại: Code ví dụ Hibernate EntityManager, EntityManagerFactory)
(Xem lại: Code ví dụ Hibernate Session, SessionFactory)
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="persistence"> <description>Demo Hibernate Generate Custom ID</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate-generate-id" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="admin1234" /> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence>
File entity
package stackjava.com.hibernatedemo.entities; import javax.persistence.I; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "employee") public class Employee { @Id @GeneratedValue(generator = "my_generator") @GenericGenerator(name = "my_generator", strategy = "stackjava.com.hibernatedemo.generator.MyGenerator") @Column(name="id") private String id; @Column(name = "name") private String name; // getter - setter - constructor @Override public String toString() { return "Employee [id=" + id + ", name=" + name + "]"; } }
- @GeneratedValue(generator = “my_generator”): khai báo phương thức sinh id, ở đây khai báo sử dụng generator có tên là my_generator
- @GenericGenerator(name = “my_generator”, strategy = “stackjava.com.hibernatedemo.generator.MyGenerator”): khai báo generator có tên là my_generator được định nghĩa ở class stackjava.com.hibernatedemo.generator.MyGenerator
Class định nghĩa cách sinh id
package stackjava.com.hibernatedemo.generator; import java.io.Serializable; import java.util.stream.Stream; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; public class MyGenerator implements IdentifierGenerator { private String prefix = "EMP"; @Override public Serializable generate(SharedSessionContractImplementor session, Object obj) throws HibernateException { String query = "SELECT e.id FROM Employee e"; Stream<String> ids = session.createQuery(query, String.class).stream(); Long max = ids.map(o -> o.replace(prefix, "")).mapToLong(Long::parseLong).max().orElse(0L); return prefix + (String.format("%04d", max + 1)); } }
IdentifierGenerator
là interface định nghĩa Generator cho hibernate- Ở đây mình sẽ sinh id có dạng
EMP0000
sau đó tăng dần từng đơn vịEMP0001
,EMP0002
… (3 ký tự đầu tiên luôn là EMP, 4 ký tự đằng sau dạng số và tăng dần).
Mình sẽ select tất cả các id có trong table employee, tách lấy 4 số đằng sau và lấy số lớn nhất. ID được tạo ra sẽ là EMP + số lớn nhất + 1 đơn vị.
(Thay vì select từ database các bạn có thể tạo thuật toán để sinh số ngẫu nhiên ko bị trùng, hoặc lưu giá trị lớn nhất vào bộ nhớ đệm, mỗi lần tạo id sẽ lấy từ bộ nhớ đệm chứ không cần phải query từ database nữa)
Demo
package stackjava.com.hibernatedemo; import javax.persistence.*; import stackjava.com.hibernatedemo.entities.Employee; public class Demo { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Employee emp1 = new Employee("kai"); Employee emp2 = new Employee("sena"); entityManager.persist(emp1); entityManager.persist(emp2); entityManager.getTransaction().commit(); System.out.println(emp1); System.out.println(emp2); entityManager.close(); entityManagerFactory.close(); } }
Kết quả:
Check lại database:
Okay, Done!
Download code ví dụ trên tại đây.
References: