在Java Persistence API(JPA)中,我们经常会遇到需要将基本类型集合(如List或Set)持久化到数据库中的场景。JPA通过@ElementCollection注解为我们提供了一种简单而强大的方式来实现这一功能。本文将详细介绍如何使用@ElementCollection注解来映射基本类型集合,并通过实例演示如何持久化和加载这些数据。
-
基本类型集合的映射
在JPA中,要将一个基本类型集合持久化到数据库中,我们需要在实体类中使用@ElementCollection注解。这个注解会告诉JPA,被注解的字段是一个集合,并且集合中的元素是基本类型,而不是另一个实体。JPA会为这个集合创建一个单独的表,并通过外键与主实体表关联。
例如,我们有一个Customer实体类,其中包含一个List类型的phoneNumbers字段,表示客户的电话号码列表。我们可以这样定义这个实体类:
java复制
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
private String name;@ElementCollection
private List phoneNumbers;// 省略构造方法、getter和setter方法
}
在上述代码中,@ElementCollection注解被放置在phoneNumbers字段上。JPA会为Customer实体创建一个主表(Customer表),同时为phoneNumbers集合创建一个单独的表(默认命名为Customer_PhoneNumbers)。Customer_PhoneNumbers表中会包含一个外键字段(customer_id),指向Customer表的主键。 -
自定义集合表的映射
JPA默认会根据一定的命名规则来生成集合表的名称和字段。然而,我们可以通过@CollectionTable注解来自定义集合表的名称、外键名称等信息。例如,我们可以这样定义Customer类,自定义集合表的名称为CustomerPhoneNumbers:
java复制
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
private String name;@ElementCollection
@CollectionTable(name = “CustomerPhoneNumbers”, joinColumns = @JoinColumn(name = “customerId”))
private List phoneNumbers;// 省略构造方法、getter和setter方法
}
在上述代码中,@CollectionTable注解的name属性指定了集合表的名称为CustomerPhoneNumbers,joinColumns属性中的@JoinColumn注解指定了外键字段的名称为customerId。 -
持久化和加载数据
接下来,我们通过一个简单的示例来演示如何使用EntityManager来持久化和加载包含基本类型集合的实体。
3.1 持久化数据
我们可以通过EntityManager的persist方法来将Customer实体及其phoneNumbers集合持久化到数据库中。以下是一个示例代码:
java复制
public class ExampleMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(“example-unit”);
try {
persistEntity(emf);
} finally {
emf.close();
}
}private static void persistEntity(EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
Customer c1 = new Customer();
c1.setName(“Lindsey Craft”);
c1.setPhoneNumbers(Arrays.asList(“111-111-1111”, “222-222-2222”));
Customer c2 = new Customer();
c2.setName(“Morgan Philips”);
c2.setPhoneNumbers(Arrays.asList(“333-333-3333”));
em.getTransaction().begin();
em.persist(c1);
em.persist(c2);
em.getTransaction().commit();
em.close();
}
}
在上述代码中,我们创建了两个Customer对象,并为它们分别设置了电话号码列表。然后,我们通过EntityManager的persist方法将这些对象持久化到数据库中。
3.2 加载数据
我们可以通过EntityManager的查询方法来加载包含基本类型集合的实体。以下是一个示例代码:
java复制
public class ExampleMain2 {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(“example-unit”);
try {
loadEntity(emf);
} finally {
emf.close();
}
}private static void loadEntity(EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
List customers = em.createQuery(“SELECT c FROM Customer c”, Customer.class).getResultList();
for (Customer customer : customers) {
System.out.println(customer.getName() + ": " + customer.getPhoneNumbers());
}
em.close();
}
}
在上述代码中,我们通过EntityManager的createQuery方法执行了一个JPQL查询,加载了所有Customer对象及其电话号码列表,并将它们打印出来。 -
数据库表结构和数据
在执行上述代码后,数据库中会生成以下表结构:
Customer表:
id(主键)
name
CustomerPhoneNumbers表(假设我们使用了自定义的集合表名称):
customerId(外键,指向Customer表的id)
phoneNumbers
以下是插入数据后的表数据:
Customer表:
idname1Lindsey Craft2Morgan Philips
CustomerPhoneNumbers表:
customerIdphoneNumbers1111-111-11111222-222-22222333-333-3333 -
总结
本文通过一个简单的示例,详细介绍了如何在JPA中使用@ElementCollection注解来映射基本类型集合,并通过EntityManager进行数据的持久化和加载。@ElementCollection为我们提供了一种方便的方式来处理基本类型集合的持久化,而@CollectionTable注解则允许我们对集合表的映射进行自定义。通过这种方式,我们可以轻松地将包含基本类型集合的实体持久化到数据库中,并在需要时加载它们。
希望本文对你有所帮助!