JavaPersistenceAPI:数据库交互与实体操作全解析
立即解锁
发布时间: 2025-08-18 02:36:47 阅读量: 3 订阅数: 4 

### Java Persistence API:数据库交互与实体操作全解析
在Java开发中,与数据库进行交互是一项常见且重要的任务。Java Persistence API(JPA)为我们提供了一种方便的方式来实现这一目标。本文将详细介绍JPA的基本操作、实体自动生成、命名查询、Bean验证以及实体关系等方面的内容。
#### 1. JPA基本操作方法
JPA提供了一些基本方法来执行CRUD(Create, Read, Update, Delete)操作。
- **edit()方法**:用于更新现有实体。它接受一个JPA实体的实例作为唯一参数,该方法会调用`EntityManager`的`merge()`方法,将JPA实体中的数据更新到数据库中。
- **destroy()方法**:用于删除实体。它接受要删除对象的主键作为唯一参数。首先会检查该对象是否存在于数据库中,如果不存在则抛出异常,否则调用`EntityManager`的`remove()`方法从数据库中删除相应的行。
#### 2. 自动生成JPA实体
在许多项目中,我们会使用数据库管理员创建的现有数据库模式。NetBeans可以从现有的数据库模式自动生成JPA实体,这为我们节省了大量可能繁琐的工作。以下是具体的操作步骤:
1. **创建数据库模式**:
- 打开Services窗口,展开Databases,右键单击JavaDB,选择Create Database...选项。
- 在Create Java DB Database向导中添加数据库信息。
- 打开SQL脚本文件`create_populate_tables.sql`(该文件包含在相关资源包中),通过File | Open File...导航到其在磁盘上的位置并打开。
- 从Connection组合框中选择新创建的连接`customerdb`。
- 点击执行按钮执行数据库脚本,此时数据库将创建多个表。
2. **生成JPA实体**:
- 创建一个新项目,选择File | New,在New File对话框中选择Persistence类别和Entity Classes from Database文件类型。这里以Web Application项目为例。
- 可以选择现有的数据源,或者像前面的例子一样“即时”创建一个新的数据源,并选择之前创建的数据库连接。
- 选择一个或多个表来生成JPA实体,如果要为所有表创建JPA实体,可点击Add All按钮。
- 点击Next后,NetBeans允许我们更改生成类的名称,同时需要指定类的包名,并建议勾选Generate Named Query Annotations for Persistent Fields复选框。还可以选择生成JAXB注解并创建持久化单元。
- 在向导的下一个屏幕中,可以选择关联实体的获取方式(急切或懒惰),默认情况下,一对一和多对一关系是急切获取,一对多和多对多关系是懒惰获取。
- 可以选择用于一对多或多对多关系中多端的集合类型,默认值是`java.util.Collection`,其他有效值包括`java.util.List`和`java.util.Set`。
- 勾选不同的复选框会有不同的效果:
- Fully Qualified Database Table Names:将表的目录和模式元素映射到每个生成实体的`@Table`注解中。
- Attributes for Regenerating Tables:生成的`@Column`注解将具有长度、可空性、精度和比例等属性,还会为`@Table`注解添加`uniqueConstraints`属性。
- Use Column Names in Relationships:一对多和一对一关系的字段将根据数据库表中的列名命名,通常取消勾选此复选框会使实体关系中的字段名称更易读。
- Use Defaults if Possible:NetBeans仅生成覆盖默认行为的注解。
- Generate Fields for Unresolved Relationships:NetBeans会生成无法解析实体的字段。
- 点击Finish后,NetBeans将为数据库中的所有表生成JPA实体。
以下是生成的`Customer` JPA实体示例:
```java
package com.ensode.jpa;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
@Table(name = "CUSTOMER")
@NamedQueries({
@NamedQuery(name = "Customer.findAll", query = "SELECT c FROM Customer c"),
@NamedQuery(name = "Customer.findByCustomerId", query = "SELECT c FROM Customer c WHERE c.customerId = :customerId"),
@NamedQuery(name = "Customer.findByFirstName", query = "SELECT c FROM Customer c WHERE c.firstName = :firstName"),
@NamedQuery(name = "Customer.findByMiddleName", query = "SELECT c FROM Customer c WHERE c.middleName = :middleName"),
@NamedQuery(name = "Customer.findByLastName", query = "SELECT c FROM Customer c WHERE c.lastName = :lastName"),
@NamedQuery(name = "Customer.findByEmail", query = "SELECT c FROM Customer c WHERE c.email = :email")})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "CUSTOMER_ID")
private Integer customerId;
@Size(max = 20)
@Column(name = "FIRST_NAME")
private String firstName;
@Size(max = 20)
@Column(name = "MIDDLE_NAME")
private String middleName;
@Size(max = 20)
@Column(name = "LAST_NAME")
private String lastName;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//
// if the field contains email address consider using this annotation to enforce field validation
@Size(max = 30)
@Column(name = "EMAIL")
private String email;
@OneToMany(mappedBy = "customer")
private Collection<Telephone> telephoneCollection;
@OneToMany(mappedBy = "customer")
private Collection<CustomerOrder> customerOrderCollection;
@OneToMany(mappedBy = "customer")
private Collection<Address> addressCollection;
//generated constructors and methods omitted for brevity.
}
```
这里我们可以看到NetBeans生成的类带有`@Entity`注解,表明该类是一个JPA实体。根据表的主键约束,NetBeans会自动为其中一个字段添加`@Id`注解,并且没有使用主键生成策略,我们要么自己填充主键,要么手动添加`@GeneratedValue`注解。`@Basic`注解用于标记该字段为非可选。`@Table`注解是可选的,它指示JPA实体映射到的表名,如果不使用该注解,实体将映射到与实体类同名的表(不区分大小写)。
#### 3. 命名查询和JPQL
在生成的代码中,如果勾选了Generate Named Query Annotations for Persistent Fields复选框,会出现`@NamedQueries`注解。该注解包含一个`value`属性,其值是一个`@NamedQuery`注解数组。`@NamedQuery`注解有一个`name`属性,用于给查询一个逻辑名称(通常使用JPA实体名称作为查询名称的一部分),以及一个`query
0
0
复制全文
相关推荐










