原文: https://howtodoinjava.com/hibernate/hibernate-many-to-many-mapping-using-annotations/
在两个实体之间建立多对多 Hiberate 的映射,其中一个实体可以与多个其他实体实例相关。 例如,对于订阅服务,SubscriptionEntity和ReaderEntity可以是两种类型的实体。 任何订阅都可以有多个阅读器,其中一个阅读器可以订阅多个订阅。
在此 hibernate 教程中,我们将学习使用 hibernate 在数据库中创建多对多映射。
Table of contentsHibernate many to many mapping designOwner entityMapped entityConfigure entities in hibernate config fileDemo
1. Hiberate 多对多映射设计
为了演示使用 Hiberate 注解的多对多映射,我们将关联两个实体,即ReaderEntity和SubscriptionEntity。
他们的数据库架构应如下所示。 使用这些表,任何应用都可以保存读者和订阅之间的多个关联。

2. 所有者实体
所有者实体是负责建立关联并维护它的实体。 在我们的情况下,我将ReaderEntity设置为所有者实体。 @JoinTable注解已用于建立此关联。
package hibernate.test.manyToMany.joinTable;import java.io.Serializable;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.Table;import javax.persistence.UniqueConstraint;@Entity(name = "ReaderEntity")@Table(name = "READER", uniqueConstraints = {@UniqueConstraint(columnNames = "ID"),@UniqueConstraint(columnNames = "EMAIL") })public class ReaderEntity implements Serializable{private static final long serialVersionUID = -1798070786993154676L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "ID", unique = true, nullable = false)private Integer readerId;@Column(name = "EMAIL", unique = true, nullable = false, length = 100)private String email;@Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)private String firstName;@Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)private String lastName;@ManyToMany(cascade=CascadeType.ALL)@JoinTable(name="READER_SUBSCRIPTIONS", joinColumns={@JoinColumn(referencedColumnName="ID")}, inverseJoinColumns={@JoinColumn(referencedColumnName="ID")})private Set<SubscriptionEntity> subscriptions;//Getters and setters}
3. 映射实体
我们的映射实体是SubscriptionEntity,它使用“mappingBy”属性映射到ReaderEntity。
package hibernate.test.manyToMany.joinTable;import java.io.Serializable;import java.util.Set;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.ManyToMany;import javax.persistence.Table;import javax.persistence.UniqueConstraint;@Entity(name = "SubscriptionEntity")@Table(name = "SUBSCRIPTION", uniqueConstraints = {@UniqueConstraint(columnNames = "ID")})public class SubscriptionEntity implements Serializable{private static final long serialVersionUID = -6790693372846798580L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "ID", unique = true, nullable = false)private Integer subscriptionId;@Column(name = "SUBS_NAME", unique = true, nullable = false, length = 100)private String subscriptionName;@ManyToMany(mappedBy="subscriptions")private Set<ReaderEntity> readers;//Getters and setters}
4. 在 Hiberate 配置文件中配置实体
我们使两个实体都可以在运行时使用。 为此,我们必须将它们添加到hibernate.cfg.xml文件中。
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatetest</property><property name="hibernate.connection.password">XXXXXX</property><property name="hibernate.connection.username">root</property><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><property name="show_sql">true</property><property name="hbm2ddl.auto">create</property><mapping class="hibernate.test.manyToMany.joinTable.ReaderEntity"/><mapping class="hibernate.test.manyToMany.joinTable.SubscriptionEntity"/></session-factory></hibernate-configuration>
5. Hiberate 多对多注解映射示例
现在,该测试代码了。 我编写了以下代码来测试上述实体及其多对多关系。
package hibernate.test.manyToMany;import hibernate.test.HibernateUtil;import hibernate.test.manyToMany.joinTable.*;import java.util.HashSet;import java.util.Set;import org.hibernate.Session;public class TestJoinTable{public static void main(String[] args){Session session = HibernateUtil.getSessionFactory().openSession();session.beginTransaction();//Add subscriptionSubscriptionEntity subOne = new SubscriptionEntity();subOne.setSubscriptionName("Entertainment");SubscriptionEntity subTwo = new SubscriptionEntity();subTwo.setSubscriptionName("Horror");Set<SubscriptionEntity> subs = new HashSet<SubscriptionEntity>();subs.add(subOne);subs.add(subTwo);//Add readersReaderEntity readerOne = new ReaderEntity();readerOne.setEmail("demo-user1@mail.com");readerOne.setFirstName("demo");readerOne.setLastName("user");ReaderEntity readerTwo = new ReaderEntity();readerTwo.setEmail("demo-user2@mail.com");readerTwo.setFirstName("demo");readerTwo.setLastName("user");Set<ReaderEntity> readers = new HashSet<ReaderEntity>();readers.add(readerOne);readers.add(readerTwo);readerOne.setSubscriptions(subs);readerTwo.setSubscriptions(subs);session.save(readerOne);session.save(readerTwo);session.getTransaction().commit();HibernateUtil.shutdown();}}
程序输出:
Hibernate: insert into READER (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)Hibernate: insert into SUBSCRIPTION (SUBS_NAME) values (?)Hibernate: insert into SUBSCRIPTION (SUBS_NAME) values (?)Hibernate: insert into READER (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)Hibernate: insert into READER_SUBSCRIPTIONS (readers_ID, subscriptions_ID) values (?, ?)Hibernate: insert into READER_SUBSCRIPTIONS (readers_ID, subscriptions_ID) values (?, ?)Hibernate: insert into READER_SUBSCRIPTIONS (readers_ID, subscriptions_ID) values (?, ?)Hibernate: insert into READER_SUBSCRIPTIONS (readers_ID, subscriptions_ID) values (?, ?)
在此示例中,我们了解了在 Hiberate 中使用多对多注解来连接表。
学习愉快!
