Code ví dụ Hibernate @EmbeddedId, @Embeddable, Id gồm nhiều column.
(Xem thêm: Hướng dẫn tự học Hibernate)
Thông thường, khi tạo bảng, khóa chính thường sẽ là 1 column (có thể là kiểu text, int, tự tăng…). Tuy nhiên trong nhiều trường hợp ta cần sử dụng kết hợp nhiều column để làm khóa chính, Ví dụ bảng trung gian cho trường hợp ManyToMany thì người ta sẽ dùng luôn 2 khóa chính của 2 bảng để làm khóa chính cho bảng trung gian.
Trong ví dụ này mình sẽ hướng dẫn cách mapping từ Table sang Class Java cho trường hợp sử dụng nhiều column để làm khóa chính (primary key)
Các công nghệ sử dụng:
Tạo database MySQL
CREATE SCHEMA `hibernate-demo-3` ; CREATE TABLE `hibernate-demo-3`.`employee` ( `first_name` VARCHAR(45) NOT NULL, `last_name` VARCHAR(45) NOT NULL, `address` VARCHAR(255) NULL, PRIMARY KEY (`first_name`, `last_name`));
Ví dụ mình tạo table employee
khóa chính xác định bởi 2 column là first_name
và last_name
tức là mỗi cặp này là duy nhất.
Cấu trúc Project
Các 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>HibernateEnumDemo</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, kết nối tới MySQL
<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 Entity Manager</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-demo-3" /> <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>
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)
File entity
package stackjava.com.hibernatedemo.entities; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table(name = "employee") public class Employee { @EmbeddedId private Pk pk; @Column(name = "address") private String address; // setter - getter @Embeddable public static class Pk implements Serializable { private static final long serialVersionUID = 1L; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; public String getFirstName() { return firstName; } @Override public String toString() { return "Pk [firstName=" + firstName + ", lastName=" + lastName + "]"; } // setter - getter } @Override public String toString() { return "Employee [pk=" + pk + ", address=" + address + "]"; } }
- Để định nghĩa id, primary key cho class ta sử tạo 1 class khác gồm các field tương ứng với các column sử dụng làm khóa chính sau đó sử dụng annotation
@Embeddable
để đánh dấu class này sử dụng là Id. - Thường class sử dụng làm Id chỉ dùng cho class gọi tới nó để làm Id nên mình sẽ để class này là inner class. Trong ví dụ này mình tạo inner class
Pk
để làm khóa. (Lưu ý, class Pk phảiimplements Serializable
) - Khi khai báo Id cho trường hợp Id là 1 class khác ta dùng annotation
@EmbeddedId
thay vì annotation@Id
Demo Insert đối tượng với khóa chính nhiều hơn 1 field
package stackjava.com.hibernatedemo; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import stackjava.com.hibernatedemo.entities.Employee; public class DemoInsert { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Employee emp = new Employee(); Employee.Pk pk = new Employee.Pk(); pk.setFirstName("kai"); pk.setLastName("tran"); emp.setPk(pk); emp.setAddress("ha noi - viet nam"); entityManager.persist(emp); entityManager.getTransaction().commit(); System.out.println(emp); entityManager.close(); entityManagerFactory.close(); } }
Ta tạo đối tượng Pk
và set nó vào đối tượng Employee
và persist như bình thường
Kết quả:
Hibernate: insert into employee (address, first_name, last_name) values (?, ?, ?) Employee [pk=Pk [firstName=kai, lastName=tran], address=ha noi - viet nam]
Demo select đối tượng với khóa chính nhiều hơn 1 field
package stackjava.com.hibernatedemo; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import stackjava.com.hibernatedemo.entities.Employee; public class DemoSelect { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); Employee.Pk pk = new Employee.Pk(); pk.setFirstName("kai"); pk.setLastName("tran"); Employee emp = entityManager.find(Employee.class, pk); System.out.println(emp); entityManager.close(); entityManagerFactory.close(); } }
Kết quả:
Hibernate: select employee0_.first_name as first_na1_0_0_, employee0_.last_name as last_nam2_0_0_, employee0_.address as address3_0_0_ from employee employee0_ where employee0_.first_name=? and employee0_.last_name=? Employee [pk=Pk [firstName=kai, lastName=tran], address=ha noi - viet nam]
Okay, Done!
Download code ví dụ trên tại đây.
References: