# Hiberate 多对多映射注解示例

> 原文： [https://howtodoinjava.com/hibernate/hibernate-many-to-many-mapping-using-annotations/](https://howtodoinjava.com/hibernate/hibernate-many-to-many-mapping-using-annotations/)

**在两个实体之间建立多对多 Hiberate 的映射**，其中一个实体可以与多个其他实体实例相关。 例如，对于订阅服务，`SubscriptionEntity`和`ReaderEntity`可以是两种类型的实体。 任何订阅都可以有多个阅读器，其中一个阅读器可以订阅多个订阅。

在此 hibernate 教程中，我们将学习使用 hibernate 在数据库中创建多对多映射。

```java
Table of contents

Hibernate many to many mapping design
Owner entity
Mapped entity
Configure entities in hibernate config file
Demo
```

## 1\. Hiberate 多对多映射设计

为了演示使用 Hiberate 注解的多对多映射，我们将关联两个实体，即`ReaderEntity`和`SubscriptionEntity`。

他们的数据库架构应如下所示。 使用这些表，任何应用都可以保存读者和订阅之间的多个关联。

![many-to-many-hibernate-mapping](img/a403dccaddaa88a2a29af744de1e2502.png "many-to-many-hibernate-mapping")

## 2\. 所有者实体

所有者实体是**负责建立关联并维护它的实体**。 在我们的情况下，我将`ReaderEntity`设置为所有者实体。 `@JoinTable`注解已用于建立此关联。

```java
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`。

```java
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`文件中。

```java
<?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 多对多注解映射示例

现在，该测试代码了。 我编写了以下代码来测试上述实体及其多对多关系。

```java
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 subscription
		SubscriptionEntity 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 readers
		ReaderEntity 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();
	}
}

```

程序输出：

```java
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 (?, ?)

```

[下载源码](https://drive.google.com/file/d/0B7yo2HclmjI4ZHdoLVF2Zk1Xc1E/view?usp=drive_web "download example of many to many mapping")

在此示例中，我们了解了在 Hiberate 中**使用多对多注解来连接表**。

学习愉快！