# Hibernate / JPA2 持久化注解教程
> 原文: [https://howtodoinjava.com/hibernate/hibernate-jpa-2-persistence-annotations-tutorial/](https://howtodoinjava.com/hibernate/hibernate-jpa-2-persistence-annotations-tutorial/)
此 [**Hibernate**](//howtodoinjava.com/hibernate-tutorials/ "Hibernate Tutorials")(或 JPA2)持久化注解教程包含对 Java POJO 进行注解以使其充当持久化 JPA 实体时可能需要的所有重要注解的概述。 本教程首先定义一个 POJO “`EmployeeEntity`”,在其中定义一些属性,并具有各自的获取器和设置器方法。 在学习新注解时,我们将这些注解应用于`EmployeeEntity`,然后我们将了解该特定注解的含义。
让我们快速列出注解,我们将在本教程中进行讨论。
```java
Table of Contents
**Most used JPA Annotations**
Entity Beans with `@Entity`
Primary Keys with `@Id` and `@GeneratedValue`
Generating Primary Key Values with `@SequenceGenerator`
Generating Primary Key Values with `@TableGenerator`
Compound Primary Keys with `@Id`, `@IdClass`, or `@EmbeddedId`
Database Table Mapping with `@Table` and `@SecondaryTable`
Persisting Basic Types with `@Basic`
Omitting Persistence with `@Transient`
Mapping Properties and Fields with `@Column`
**Modeling Entity Relationships**
**Mapping Inheritance Hierarchies**
Single Table
Joined Table
Table per Concrete Class
**Other JPA2 Persistence Annotations**
Temporal Data with `@Temporal`
Element Collections with `@ElementCollection`
Large Objects with `@Lob`
Mapped Superclasses with `@MappedSuperclass`
Ordering Collections with `@OrderColumn`
**Named Queries (HQL or JPQL)**
`@NamedQuery` and `@NamedQueries`
Named Native Queries using `@NamedNativeQuery`
```
上面的列表是一个很大的列表,列出的项目的完整详细信息的范围较小,但是我将尝试包括所有相关信息,这将有助于您做出决定。 首先,我们写下`EmployeeEntity` POJO,然后在整个讨论中开始使用`JPA annotations`装饰它。
```java
package com.howtodoinjava.demo.test;
import java.io.Serializable;
public class EmployeeEntity implements Serializable
{
private static final long serialVersionUID = 570235488278506106L;
private Integer employeeId;
private String firstName;
private String lastName;
public Integer getEmployeeId()
{
return employeeId;
}
public void setEmployeeId(Integer employeeId)
{
this.employeeId = employeeId;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
}
```
## 最常用的 JPA 注解
## Hibernate / JPA2 `@Entity`注解教程
这是将 POJO 标记为 JPA 实体的第一步。 为此,我们需要应用`@Entity`注解,如下所示:
```java
import javax.persistence.Entity;
@Entity
public class EmployeeEntity implements Serializable
{
public EmployeeEntity(){
}
//Other code
}
```
JPA2 标准注解包含在`javax.persistence`包中,因此我们从此包中导入了注解。 `@Entity`注解将该类标记为实体 Bean,因此它**必须具有无参数构造器**,该构造器至少在受保护的范围(特定于 JPA)下可见。 Hibernate 至少支持包作用域,但是您会失去对其他 JPA 实现的可移植性,因为它们可能只允许受保护级别作用域。 理想情况下,您应该将此构造器公开,这也使其与其他规范高度兼容。 还有更多规则,例如 POJO 类的欲望不是最终的。 而且也不能是抽象的。
现在,让我们快速浏览一下“`@org.hibernate.annotations.Entity`”注解(特定于 Hiberate)。 使用它,您可以为特定于 Hiberate 的实体定义一些额外的行为。
`@javax.persistence.Entity`仍然是强制性的,`@org.hibernate.annotations.Entity`是一种鼓励,而不是替代。
```java
@javax.persistence.Entity
@org.hibernate.annotations.Entity(
selectBeforeUpdate = true,
dynamicInsert = true, dynamicUpdate = true,
optimisticLock = OptimisticLockType.ALL,
polymorphism = PolymorphismType.EXPLICIT,
mutable = false)
public class EmployeeEntity implements Serializable
{
public EmployeeEntity(){
}
//Other code
}
```
所有上述属性在很久以前就已被标记为已弃用,但仍受支持。 我仅给出示例供参考。
实际上,在新版本的 Hiberate 下,您根本不需要使用`@org.hibernate.annotations.Entity`。 相反,您可以仅使用注解直接添加所需的行为。 让我们看一下上面编写的实体的等效代码。
```java
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.OptimisticLockType;
import org.hibernate.annotations.OptimisticLocking;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.annotations.SelectBeforeUpdate;
@javax.persistence.Entity
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Polymorphism (type = PolymorphismType.EXPLICIT)
@OptimisticLocking (type = OptimisticLockType.ALL)
public class EmployeeEntity implements Serializable
{
public EmployeeEntity(){
}
//Other code
}
```
继续,如果需要,在代码中使用这些注解。
## 使用`@Id`和`@GeneratedValue`的主键
每个实体 bean 必须具有一个主键,您可以在主类上使用`@Id`注解对其进行注解。 通常,主键将是单个字段,尽管它也可以是多个字段的组合,我们将在后面的部分中看到。
`@Id`注解的位置决定了 Hibernate 将用于映射的默认访问策略。 如果将注解应用于字段,如下所示,则将使用“字段访问”。
```java
@Id
private Integer employeeId;
```
相反,如果将注解应用于字段的访问器,则将使用属性访问。
```java
@Id
public Integer getEmployeeId()
{
return employeeId;
}
```
属性访问意味着 Hibernate 将调用获取器和设置器,而不是直接直接设置字段,而在字段访问的情况下,它会这样做。 如果需要,这可以灵活地更改在`id`字段中设置的实际值的值。 此外,您还可以在设置器中为其他字段设置“`id`”字段时应用额外的逻辑。
默认情况下,`@Id`注解不会创建主键生成策略,这意味着作为代码的作者,您需要通过设置显式调用设置器方法的方式来确定有效的主键。 或者,您可以使用`@GeneratedValue`注解。
`@GeneratedValue`注解具有一对属性:`strategy`和`generator `如下:
```java
@Id
@GeneratedValue (strategy = GenerationType.SEQUENCE)
private Integer employeeId;
//OR a more complex use can be
@Id
@GeneratedValue(strategy=GenerationType.TABLE , generator="employee_generator")
@TableGenerator(name="employee_generator",
table="pk_table",
pkColumnName="name",
valueColumnName="value",
allocationSize=100)
private Integer employeeId;
```
策略属性必须是`javax.persistence.GeneratorType`枚举中的值。 如果未指定生成器类型,则默认为`AUTO`。 `GeneratorType`上有四种不同类型的主键生成器,如下所示:
1. **`AUTO`**:Hibernate 根据数据库对主键生成的支持来决定使用哪种生成器类型。
2. **`IDENTITY`**:数据库负责确定和分配下一个主键。
3. **`SEQUENCE`**:某些数据库支持`SEQUENCE`列类型。 它使用`@SequenceGenerator`。
4. **`TABLE`**:此类型保留一个带有主键值的单独表。 它使用`@TableGenerator`。
`generator`属性允许使用上面的代码示例中所示的自定义生成机制。
## 使用`@SequenceGenerator`生成主键值
序列是一个数据库对象,可用作主键值的源。 它与标识列类型的使用类似,不同之处在于序列独立于任何特定表,因此可以被多个表使用。
要声明要使用的特定序列对象及其属性,必须在带注解的字段上包含`@SequenceGenerator`注解。 这是一个例子:
```java
@Id
@SequenceGenerator(name="seq1",sequenceName="HIB_SEQ")
@GeneratedValue(strategy=SEQUENCE,generator="seq1")
private Integer employeeId;
```
在此,已声明了名为`seq1`的序列生成注解。 这指的是称为`HIB_SEQ`的数据库序列对象。 然后,将名称`seq1`引用为`@GeneratedValue`注解的生成器属性。 仅序列生成器名称是必需的; 其他属性将采用合理的默认值,但是作为一种好的做法,您应该为`sequenceName`属性提供一个明确的值。 如果未指定,则持久化供应器将选择要使用的`sequenceName`值。
## 使用`@TableGenerator`生成主键值
`@TableGenerator`注解的使用方式与`@SequenceGenerator`注解非常相似,但是由于`@TableGenerator`操纵标准数据库表来获取其主键值,因此无需使用特定于供应商的序列对象,因此可以保证 在数据库平台之间可移植。
为了获得最佳的可移植性和最佳性能,您不应指定使用表生成器,而应使用`@GeneratorValue(strategy=GeneratorType.AUTO)`配置,该配置允许持久性提供程序为数据库选择最合适的策略。
与序列生成器一样,`@TableGenerator`的名称属性是必需的,其他属性是可选的,并且表详细信息由持久化供应器选择。 让我们再来看一个例子。
```java
@Id
@GeneratedValue(strategy=GenerationType.TABLE , generator="employee_generator")
@TableGenerator(name="employee_generator",
table="pk_table",
pkColumnName="name",
valueColumnName="value",
allocationSize=100)
private Integer employeeId;
```
可选属性如下:
* **`allocationSize`**:允许一次设置主键的数量以提高性能。
* **`catalog`**:允许指定表所在的目录。
* **`initialValue`**:允许指定起始主键值。
* **`pkColumnName`**:允许标识表的主键列。 该表可以包含为多个实体生成主键值所需的详细信息。
* **`pkColumnValue`**:允许标识包含主键生成信息的行的主键。
* **schema**:允许指定表所在的模式。
* **`table`**:包含主键值的表的名称。
* **`uniqueConstraints`**:允许将其他约束应用于表以生成模式。
* **`valueColumnName`**:允许标识包含当前实体的主键生成信息的列。
因为该表可用于包含各种条目的主键值,所以使用该表的每个实体可能只有一行。 因此,它需要自己的主键(`pkColumnName`),以及包含从中获取主键的任何实体要使用的下一个主键值(`pkColumnValue`)的列。
## 使用`@Id`,`@IdClass`或`@EmbeddedId`的复合主键
尽管出于各种原因使用单列代理键是有利的,但有时您可能不得不使用业务键。 当它们包含在单个列中时,您可以使用`@Id`而无需指定生成策略,该策略强制用户在持久保存实体之前分配主键值。
但是,如果是多列主键,则必须创建一个代表该主键的类。 当然,它不需要自己的主键,但它必须是公共类,必须具有默认构造器,必须可序列化,并且必须[**实现`hashCode()`和`equals()`方法**](//howtodoinjava.com/java/related-concepts/working-with-hashcode-and-equals-methods-in-java/ "Working with hashCode and equals methods in java"),以允许 Hibernate 代码测试主键冲突。
一旦创建了此主键类,就可以使用以下三种策略:
1. 将其标记为`@Embeddable`并为其添加一个普通属性,并标记为`@Id`。
2. 向您的实体类添加一个普通属性,标记为`@EmbeddableId`。
3. 将属性的所有字段添加到您的实体类中,用`@Id`标记它们,并用`@IdClass`标记您的实体类,以提供主键类的类。
使用带有标记为`@Embeddable`的类的`@Id`是最自然的方法。 无论如何,`@Embeddable`标签可用于非主键可嵌入值。 它允许您将复合主键视为单个属性,并允许在其他表中重用`@Embeddable`类。
值得一提的是:嵌入式主键类必须可序列化。
> 可以在这里阅读详细的示例: [http://docs.oracle.com/javaee/6/api/javax/persistence/Embeddable.html](https://docs.oracle.com/javaee/6/api/javax/persistence/Embeddable.html)
## 使用`@Table`和`@SecondaryTable`进行数据库表映射
默认情况下,表名称是从实体名称派生的。 因此,给定一个带有简单`@Entity`注解的`Employee`类,表名将为“`employee`”,并根据数据库的配置进行了调整。 如果实体名称发生更改(通过在`@Entity`注解中提供其他名称,例如`@Entity("EMP_MASTER")`,则新名称将用作表名。
可以进一步自定义表名,并且可以通过`@Table`注解配置其他与数据库相关的属性。 该注解允许您指定表的许多详细信息,这些详细信息将用于将实体保留在数据库中。 如前所述,如果省略注解,则 Hibernate 将默认使用类名作为表名,因此,如果要覆盖该行为,则只需提供此注解。 `@Table`注解提供了四个属性,使您可以覆盖表的名称,表的目录及其架构,并对表中的列实现唯一约束。 通常,您只能提供一个替代表名称,例如:`@Table(name="ORDER_HISTORY")`。 如果数据库模式是从带注解的类生成的,则将应用唯一约束,并将补充任何特定于列的约束。 否则不会强制执行。
`@SecondaryTable`注解提供了一种对实体 bean 进行建模的方法,该实体 bean 跨多个不同的数据库表保留。 在这里,除了为主数据库表提供`@Table`注解之外,您的实体 bean 还可以具有`@SecondaryTable`注解或包含零个或多个`@SecondaryTable`注解的`@SecondaryTables`注解。 `@SecondaryTable`注解具有与`@Table`注解相同的基本属性,但附加了`join`属性。 `join`属性定义主数据库表的连接列。 它接受`javax.persistence.PrimaryKeyJoinColumn`对象的数组。 如果省略`join`属性,则将假定表在相同名称的主键列上进行了连接。
从辅助表中提取实体中的属性时,必须使用`@Column`注解对其进行标记,并使用表属性标识适当的表。
```java
@Entity
@Table(name = "employee")
@SecondaryTable(name = "employee_details")
public class EmployeeEntity implements Serializable
{
@Id
@GeneratedValue (strategy = GenerationType.SEQUENCE)
private Integer employeeId;
private String firstName;
private String lastName;
@Column(table = "employee_details")
public String address;
}
```
通过在`@Table`或`@SecondaryTable`的`uniqueConstraints`属性中添加一个或多个适当的`@UniqueConstraint`注解,可以将主表或辅助表中的列标记为具有唯一值。 或者,您也可以在`@Column`属性上的`unique`属性在字段级别设置唯一性。
```java
@Entity
@Table(
name="employee",
uniqueConstraints={@UniqueConstraint(columnNames="firstName")}
)
@SecondaryTable(name = "employee_details")
public class EmployeeEntity implements Serializable{
}
```
## 使用`@Basic`保留基本类型
默认情况下,POJO 中的属性和实例变量是持久化的。 Hibernate 将为您存储它们的值。 因此,最简单的映射适用于“基本”类型。 这些包括基本类型,基本类型包装器,基本类型或包装器数组,枚举以及实现`Serializable`但本身不是映射实体的任何类型。
这些都隐式映射 - 无需注解。 默认情况下,此类字段被映射到单个列,并且热切获取用于检索它们(即,当从数据库中检索实体时,将检索所有基本字段和属性)。 同样,当字段或属性不是基元时,可以将其存储和检索为空值。
通过将`@Basic`注解应用于适当的类成员,可以覆盖此默认行为。 注解具有两个可选属性,并且本身是完全可选的。 第一个属性被命名为可选,并带有一个布尔值。 默认为`true`,可以将其设置为`false`,以提示架构生成应创建关联列`NOT NULL`。 第二个名为`fetch`,它采用枚举`FetchType`的成员。 默认情况下为`EAGER`,但可以设置为`LAZY`以允许在访问值时加载。
```java
@Basic (fetch = FetchType.LAZY, optional = false)
private String firstName;
```
延迟加载的使用不太可能有价值,除非将大型可序列化对象映射为基本类型(而不是为其提供给定的实体映射),并且检索时间可能变得很长。 虽然必须遵守(默认)`EAGER`值,但是`LAZY`标志被视为提示,并且可以由持久化引擎忽略。
通常会省略`@Basic`属性,而使用`@Column`属性,否则可能会使用`@Basic`注解的可选属性来提供`NOT NULL`行为。
## 使用`@Transient`省略持久化
某些字段(例如,计算值)只能在运行时使用,并且应将它们保留在数据库中,并从对象中将其丢弃。 JPA 规范为这些瞬态字段提供了`@Transient`注解。 `@Transient`注解没有任何属性 - 您只需将其添加到实例变量或适合实体 bean 的属性访问策略的设置器方法中即可。
`@Transient`注解突出显示了在 Hibernate 中使用注解和使用 XML 映射文档之间的重要区别之一。 使用注解,Hibernate 将默认保留所有字段在映射对象上的持久化。 使用 XML 映射文档时,Hibernate 要求您明确告诉它哪些字段将被保留。
例如,如果我们的`EmployeeEntity`有两个附加字段“`age`”和“`dateOfBirth`”,则您想将`dateOfBirth`存储在数据库中,但是您想根据`dateOfBirth`的值来计算运行时的年龄。 因此,“`age`”字段必须标记为瞬态。
```java
@Transient
private Integer age;
```
## 使用`@Column`映射属性和字段
`@Column`注解用于指定字段或属性将映射到的列的详细信息。 其中一些细节与架构相关,因此仅在从注解文件生成架构时才适用。 其他应用则由 Hibernate(或 JPA2 持久化引擎)在运行时应用并强制执行。 它是可选的,具有一组适当的默认行为,但是在覆盖默认行为或需要将对象模型适合到预先存在的架构中时通常很有用。
以下属性通常被覆盖:
1. **`name`**:允许明确指定列的名称 - 默认情况下,这将是属性的名称。
2. **`length`** :允许显式定义用于映射值(尤其是`String`值)的列的大小。 列大小默认为 255,例如,否则可能会导致字符串数据被截断。
3. **`nullable`**:允许在生成架构时将该列标记为`NOT NULL`。 默认设置是字段应允许为空; 但是,当字段是或应该是必填字段时,通常会覆盖此字段。
4. **`unique`**:允许将该列标记为仅包含唯一值。 默认为`false`,但通常将其设置为一个值,该值可能不是主键,但是如果重复(例如用户名)仍会引起问题。
```java
@Column(name="FNAME",length=100,nullable=false)
private String firstName;
```
还有更多属性,这些属性在现实生活项目中很少使用。 这些是`table`, `insertable`, `updatable`, `columnDefinition`, `precision`和`scale`。 我将让您详细探讨它们。
## 建模实体关系
我已经在单独的详细帖子中介绍了与建模相关的概念。 请在这些链接的文章中阅读有关它们的更多信息,因为此处没有重复的信息是没有意义的。
1. [**建模`@OneToOne`关系**](//howtodoinjava.com/hibernate/hibernate-one-to-one-mapping-using-annotations/ "Hibernate one-to-one mapping using annotations")
2. [**建模`@OneToMany`关系**](//howtodoinjava.com/hibernate/hibernate-one-to-many-mapping-using-annotations/ "Hibernate one-to-many mapping using annotations")
3. [**建模`@ManyToMany`关系**](//howtodoinjava.com/hibernate/hibernate-many-to-many-mapping-using-annotations "Hibernate one-to-many mapping using annotations")
## 映射继承层次结构
实体并不总是与其他实体关联为属性; 有时,它们使用常规的 OOP 继承规则进行关联。 Hibernate 允许您使用`@Inheritance`注解来履行此类关系。
JPA2 标准和 Hibernate 都支持将继承层次结构映射到数据库中的三种方法。 这些如下:
1. **单个表(`SINGLE_TABLE`)**:每个类层次结构都有一个表
2. **已连接(`JOINED`)**:每个子类一个表(包括接口和抽象类)
3. **每类表(`TABLE_PER_CLASS`)**:每个具体类实现一个表
与继承相关的持久化实体必须使用`@Inheritance`注解进行标记。 这采用单个策略属性,该属性设置为与这些方法相对应的三个`javax.persistence.InheritanceType`枚举值之一(即`SINGLE_TABLE`,`JOINED`或`TABLE_PER_CLASS`)。
让我们详细讨论一下。
## 单表
单表方法为主要超类及其所有子类型管理一个数据库表。 超类的每个映射字段或属性以及派生类型的每个不同字段或属性都有列。 遵循此策略时,您将需要确保在层次结构中任何字段或属性名称冲突时,对列进行适当的重命名。
为了确定从数据库中检索实体时要实例化的适当类型,应在持久化层次结构的根(且仅在根中)中提供`@DiscriminatorColumn`注解。
现在让我们看一个简单的例子。 我要让您阅读更多有关 Hiberate 的官方文档中的内容。 我将在以后的文章中详细介绍它们。
```java
//The Root of the Inheritance Hierarchy Mapped with the SINGLE_TABLE Strategy
@Entity
@Inheritance(strategy = SINGLE_TABLE)
@DiscriminatorColumn(
name="DISCRIMINATOR",
discriminatorType=INTEGER
)
@DiscriminatorValue("1")
public class Book {
...
}
//A Derived Entity in the Inheritance Hierarchy
@Entity
@DiscriminatorValue("2")
public class ComputerBook extends Book {
...
}
```
## 连接表
整体式单表方法的替代方法是其他类似的联合表方法。 此处使用了“区分符”列,但各种派生类型的字段存储在不同的表中。
```java
@Entity
@Inheritance(strategy = JOINED)
@DiscriminatorColumn
name="DISCRIMINATOR"
)
public class Book {
...
}
```
## 每类表
最后,有一种每类表方法,其中继承层次结构中每种类型的所有字段都存储在不同的表中。 由于实体与其表之间的紧密对应关系,因此`@DiscriminatorColumn`注解不适用于此继承策略。
```java
@Entity
@Inheritance(strategy = TABLE_PER_CLASS)
public class Book {
...
}
```
## 其他 JPA2 持久化注解
尽管我们现在涵盖了大多数核心 JPA2 持久化注解,但是您还会经常遇到其他一些注解。 我们将在以下各节中介绍其中一些内容。
## `@Temporal`的时间数据
具有`java.util.Date`或`java.util.Calendar`类型的实体的字段或属性表示时间数据。 默认情况下,它们将存储在`TIMESTAMP`数据类型的列中,但是可以用`@Temporal`注解覆盖此默认行为。
注解接受`javax.persistence.TemporalType`枚举的单个值属性。 这提供了三个可能的值:`DATE`,`TIME`和`TIMESTAMP`。 这些分别对应于`java.sql.Date`,`java.sql.Time`和`java.sql.Timestamp`。 在架构生成时为`table`列提供了适当的数据类型。
```java
@Temporal(TemporalType.TIME)
java.util.Date startingTime;
```
## `@ElementCollection`的元素集合
除了使用一对多映射来映射集合之外,JPA2 还引入了`@ElementCollection`注解,用于映射基本或可嵌入类的集合。 您可以使用`@ElementCollection`注解来简化映射。
```java
@ElementCollection
List<String> passwordHints;
```
`@ElementCollection`注解上有两个属性`targetClass`和`fetch`。 `targetClass`属性告诉 Hibernate 集合中存储了哪个类。 如果在集合上使用泛型,则无需指定`targetClass`,因为 Hibernate 会推断出正确的类。 `fetch`属性采用枚举`FetchType`的成员。 默认情况下为`EAGER`,但可以将其设置为`LAZY`以在访问该值时允许加载。
## `@Lob`的大对象
通过应用`@Lob`注解,可以将持久化属性或字段标记为持久化数据库支持的大对象类型。
注解不带任何属性,但是将从字段或参数的类型中推断出要使用的基础大对象类型。 基于字符串和字符的类型将存储在适当的基于字符的类型中,即 CLOB。 所有其他对象将存储在 BLOB 中。
```java
@Lob
String content; // a very long article
```
`@Lob`注解可以与`@Basic`或`@ElementCollection`注解结合使用。
## 用`@MappedSuperclass`映射超类
当层次结构的根本身不是持久实体,而是派生自它的各种类时,就会发生继承的特殊情况。 这样的类可以是抽象的或具体的。 `@MappedSuperclass`注解允许您利用这种情况。
标有`@MappedSuperclass`的类不是实体,并且不可查询(不能传递给在`Session`或`EntityManager`对象中需要实体的方法)。 它不能是关联的目标。
超类列的映射信息将与派生类的详细信息存储在同一表中。
## 使用`@OrderColumn`排序集合
尽管`@OrderBy`允许从数据库中检索数据后进行排序,但 JPA2 还提供了一个注解,该注解允许在数据库中维护适当集合类型(例如`List`)的排序; 它通过维护代表该顺序的有序列来实现。 这是一个例子:
```java
@OneToMany
@OrderColumn(
name="employeeNumber"
)
List<Employee> employees;
```
在这里,我们声明一个`employeeNumber`列将保持一个值,从 0 开始,并随着每个条目添加到列表中而递增。 默认的起始值可以被 base 属性覆盖。 默认情况下,该列可以包含空(无序)值。 通过将`nullable`属性设置为`false`可以覆盖可空性。 默认情况下,从注解生成模式时,该列被假定为整数类型; 但是,可以通过提供指定不同列定义字符串的`columnDefinition`属性来覆盖此属性。
## 命名查询(HQL 或 JPQL)
## `@NamedQuery`和`@NamedQueries`
`@NamedQuery`和`@NamedQueries`允许将一个或多个 Hiberate 查询语言或 Java 持久化查询语言(JPQL)查询与实体相关联。 必需的属性如下:
1. **`name`**是用于检索查询的名称。
2. **`query`**是与名称关联的 JPQL(或 HQL)查询。
以下面的“`Author`”实体为例。
```java
@Entity
@NamedQuery(
name="findAuthorsByName",
query="from Author where name = :author"
)
public class Author {
...
}
```
该查询将按名称检索`Author`实体,因此将其与该实体相关联是很自然的。 但是,并没有实际要求以这种方式将命名查询与其所涉及的实体相关联。
您不需要直接将查询与其声明所针对的实体相关联,但是通常这样做。 如果查询与任何实体声明没有自然关联,则可以在包级别进行`@NamedQuery`注解。
## 使用`@NamedNativeQuery`和`@NamedNativeQueries`命名本地查询
`@NamedNativeQuery`允许您编写命名的 SQL 查询,而`@NamedQuery`允许您编写命名的 HQL 查询(或 JPQL)。
通常,您应该更喜欢编写 HQL 查询,因为这样您就可以让 Hibernate 处理将 HQL 转换为各种 SQL 方言的复杂过程。 当您选择切换 DBMS 供应器时,这将使您的工作简单得多。
```java
@NamedQueries({
@NamedQuery(name="get-emp-by-name",query="FROM EmployeeBean WHERE fName=:fName")
})
//Equivalent NamedNativeQuery
@NamedNativeQueries(
{
@NamedNativeQuery(
name="get-emp-by-name-native",
query="SELECT * FROM Employees WHERE firstName=:fName",
resultClass=EmployeeEntity.class)
}
)
```
简而言之,这就是本篇有限的教程,涵盖了**最重要的 JPA2 持久化注解**。 我将在以后的教程中详细介绍它们。
**祝您学习愉快!**
- HowToDoInJava Spring 教程
- Spring 5
- Spring 5 教程
- Spring 5 的新功能和增强功能
- Spring 使用注解配置 Bean
- Spring bean – XML 配置
- Spring – @Lazy加载
- Spring DispatcherServlet – 它是如何工作的?
- Spring @PostMapping示例 – @GetMapping示例
- Spring 5 MVC + Hibernate 5 示例
- Spring 和 CORS
- Spring Security 5 – Java 配置
- Spring Security 5 登录表单示例
- Spring
- Spring 教程
- Spring – IoC 容器
- Spring – 控制反转与依赖注入
- Spring 5 – Bean 范围
- Spring – Bean 生命周期
- Spring BeanPostProcessor示例
- SpringBean 自动装配 – @Autowired
- Spring 注解
- Spring – 原型注解
- Spring @Scheduled – 安排任务的 4 种方法
- Spring 定时器任务
- Spring – 应用事件
- Spring i18n – ResourceBundleMessageSource
- Spring ResourceLoaderAware - 在 Spring 中读取文件
- Spring 属性编辑器 – CustomEditorConfigurer示例
- Spring – 使用JavaMailSender发送电子邮件
- Spring 的无版本模式(最新版本)
- Spring 面试问答
- 编写配置文件的 13 个 Spring 最佳实践
- SpringBoot 2
- SpringBoot 教程
- spring-boot-starter-parent示例
- spring-boot-starter Maven 模板
- Spring Boot 多模块 Maven 项目示例
- Spring Boot 注解
- Spring Boot2 @SpringBootApplication自动配置
- Spring Boot 和 AOP
- Spring Boot 日志指南
- Spring Boot Devtools 教程
- Spring Boot WAR 包示例
- Spring Boot 2 REST API 示例
- Spring Boot Crud 操作示例与 Hibernate
- Spring Boot 2 – OAuth2 Auth 和资源服务器
- 在 Spring Boot 2 中进行测试
- Spring RestTemplate – Spring REST 客户端示例
- Spring Boot – CRUD 应用程序
- Spring Boot Hibernate 配置示例
- Spring Boot – 数据源配置
- Spring Boot 异常处理 – @ExceptionHandler示例
- Spring Boot 缓存示例教程
- 使用 Spring Boot 的 SpringRetry 模块示例
- Spring Boot Security Rest 基本身份验证示例
- Spring Boot 和 H2 数据库
- Spring Boot 2 和 ehcache 3 示例
- Spring Boot 2 与 Gson
- Spring Boot Remoting – Spring RMI 注解示例
- SpringBoot – 发送带有附件的电子邮件
- Spring Boot 面试问题
- SpringBoot
- SpringBoot – CommandLineRunner接口示例
- Spring Boot – 配置 Jetty 服务器
- Spring Boot 更改嵌入式服务器的默认端口
- Spring Boot – 更改上下文路径
- Spring Boot SSL(HTTPS)示例
- Spring Boot – 获取所有已加载的带有类类型信息的 bean
- Spring Boot – 自定义PropertyEditor配置示例
- Spring Boot @Scheduled注解示例
- Spring Boot Jersey 示例
- Spring Boot SOAP Web 服务示例
- Spring Boot SOAP 客户端 – WebServiceTemplate示例
- 带有嵌入式 ActiveMQ 的 Spring Boot JMSTemplate
- Spring Boot Hello World 示例 – Spring Boot REST 示例
- Spring Boot JSP 视图解析器示例
- SpringBoot – 执行器
- Spring Boot – 带有 JAX-RS 注解的基于角色的安全性
- Spring Boot RSS feed 和 ROAM
- Spring Boot ehcache 2 示例
- SpringBatch
- Spring Batch + Spring Boot Java 配置示例
- Spring Batch 事件监听器
- Spring Batch ItemProcessor示例
- 使用 Spring TaskScheduler进行 Spring Batch 作业调度
- Spring Batch Quartz Java 配置示例
- Spring Batch + Quartz + H2 Jdbcjobstore 示例
- 在 Quartz 作业中注入 Spring 依赖项
- Spring Batch FlatFileItemReader – 读取 CSV 示例
- Spring Batch FlatFileItemWriter – 写入 CSV 文件
- Spring Batch MultiResourceItemReader – 读取多个 CSV 文件示例
- Spring Batch 读取后删除或存档文件
- Spring Batch 已处理记录的计数示例
- Spring Batch CSV 到数据库 – Java 注解配置示例
- Spring Cloud
- 微服务 – 定义,原理和优势
- 服务监控 – Hystrix,Eureka 管理员和 Spring Boot 管理员
- Hoverfly – 微服务虚拟化示例
- ELK 堆栈示例教程
- Docker 的 Hello World 示例
- 集成 Git 的 Spring Cloud Config Server
- 使用 Netflix Eureka 进行 Spring Cloud 服务发现
- Consul 服务注册和发现示例
- Hystrix 断路器模式 – SpringCloud
- 如何将 Spring Boot 应用程序部署到 Cloud Foundry 平台
- Netflix Zuul 示例 – Zuul API 网关模式 – Spring Cloud 教程
- Spring Cloud Zipkin 和 Sleuth 示例
- Spring cloud ribbon 和 Eureka – 客户端负载均衡器示例
- Spring AOP
- Spring AOP 教程示例
- Spring AOP – AspectJ 注解配置示例
- Spring AOP + AspectJ XML 配置示例
- Spring AOP AspectJ @Before注解示例
- Spring AOP AspectJ @After注解示例
- Spring AOP AspectJ @Around注解示例
- Spring AOP AspectJ @AfterReturning注解示例
- Spring AOP AspectJ @AfterThrowing示例
- Spring AOP 事前建议示例
- Spring AOP 事后建议示例
- Spring AOP 围绕建议示例
- Spring AOP 返回后建议示例
- Spring AOP 抛出后建议示例
- Spring AOP AspectJ 切入点表达式示例
- Spring AOP – 切面顺序
- 带有加载时织入的非公开方法上的 Spring 事务
- Spring 热门 AOP 面试问题及答案
- Spring MVC
- Spring MVC 教程
- Spring MVC Hello World 示例
- 使用 Maven 和 JSTL 的 Spring MVC Hello World 示例
- Spring @RequestMapping注解示例
- Spring MVC 自定义验证器示例
- Spring Bean 验证 – JSR-303 注解
- Spring MVC 填充和验证下拉列表示例
- Spring MVC 示例 – 显示,验证和提交表单
- Spring MessageSourceAware Java Bean 示例
- Spring MVC XmlViewResolver配置示例
- Spring MVC 国际化(i18n)和本地化(i10n)示例
- Spring MVC 拦截器示例 – XML 和 Java 注解配置
- Spring HandlerInterceptor示例
- Spring MVC 在 ajax 和 jquery 中使用进度条上传多个文件
- Spring MVC 多文件上传示例
- Spring MVC 下载文件控制器示例
- Spring MVC 面试问题与答案
- Spring MVC InternalResourceViewResolver配置示例
- Spring MVC ResourceBundleViewResolver配置示例
- Spring MVC SimpleMappingExceptionResolver示例
- Spring MVC:<context:annotation-config>与<context:component-scan>
- ContextLoaderListener与DispatcherServlet
- SpringSecurity
- SpringSecurity 教程
- 具有保护切入点的 Spring 方法安全性
- Spring Security Siteminder 预身份验证示例
- Spring Security 登录表单示例
- 使用 JSP Taglibs 的 Spring 视图层安全
- Spring Security – JDBC 用户服务示例
- Spring Security UserDetailsService示例
- Spring Security 基本身份验证示例
- 使用 JUnit 测试 Spring Security Auth
- 使用@PreAuthorize和@Secured的 Spring 方法安全性
- Spring ORM
- Spring 3.2.5 AbstractRoutingDataSource示例
- Spring 3 和 Hibernate 4 集成示例教程
- Spring Hibernate 集成示例
- Spring REST
- Spring REST JSON 响应示例
- Spring REST XML 响应示例
- Spring REST 控制器示例
- 使用 JPA 配置的 Spring REST CRUD 示例
- Spring REST 异常处理示例
- Spring REST 请求主体和参数验证示例
- Spring REST 自定义令牌认证示例
- Spring REST – 多部分上传和下载示例
- Spring REST Multipart – 多部分上传示例
- Spring REST – HTTP OPTIONS 请求处理器示例
- Spring REST – 访问被拒绝请求的 JSON 响应
- Spring RestTemplate – Spring REST 客户端示例
- Spring WebFlux
- Spring WebFlux 教程
- Spring Boot WebFlux WebSocket 示例
- 使用@WebFluxTest和WebTestClient进行 Spring Boot Webflux 测试
- HowToDoInJava Java 教程
- 核心 Java 教程
- 什么是 Java 编程语言?
- 什么是 Java JDK,JRE 和 JVM – 深入分析
- Java 命名约定
- Java 类路径
- Java 变量
- Java 运算符指南
- Java 关键字
- Java 中的数据类型
- Java 中的原始数据类型
- Java 包装器类 – 自动装箱,拆箱和转换示例
- Java 中的语句类型
- Java 控制流语句
- Java 中的标签语句
- Java 字符串类指南
- Java 创建类 – 如何创建对象?
- 如何在 Java 中创建不可变的类
- Java main()方法
- Java 注释
- Java 按值传递与按引用传递
- Java 系统属性
- Java 静态 – 变量,方法,块,类和导入语句
- Java 中的静态导入语句
- Java hashCode()和equals() – 契约,规则和最佳实践
- Java this和super之间的区别
- 32 位 Java 与 64 位 Java 之间的区别
- java.exe和javaw.exe之间的区别
- Java 查看/生成类文件的字节码
- Java 中的小端和大端
- Java 命令行参数
- 在 Java 中比较浮点数或双精度数的正确方法
- Java 递归指南
- Java 偶对
- Java 元组 – 使用 Java 中的元组
- sun.misc.Unsafe类的用法
- Java UUID 生成器示例
- Java 12 教程
- Java 12 – 新特性和增强特性
- 收集器teeing()方法示例
- 字符串indent(count) – Java 中的行左缩进
- 精简数字格式
- Java 11 教程
- Java 11 的新特性和增强特性
- String.isBlank() – 在 Java 中检查空白或空字符串
- String.lines() – 获取行流 – Java 11
- String.repeat() – 在 Java 中重复字符串 N 次
- String.strip() – 删除开头和结尾的空格
- 文件readString() API – 将文件读取为 Java 中的字符串
- 文件writeString() API – 用 Java 将字符串写入文件
- Java 10 教程
- Java 10 特性和增强特性
- Java 版本 – 基于时间的发行版本控制
- Java var – 局部变量类型推断
- Java 9 教程
- Java 9 特性和增强特性
- Java 9 – 精简字符串改进 [JEP 254]
- Java 模块教程
- Java 9 – JShell
- Java – 日期流
- Java 9 Stream API 的改进
- Java 9 中的不可变集合和工厂方法
- 接口中的私有方法 – Java 9
- Java 8 教程
- Java 8 教程
- Java 8 forEach
- Java 8 流 API
- Java 流装箱示例
- Lambda 表达式
- Java 8 – 函数式接口
- Java 8 方法引用示例
- Java 默认方法教程
- Java 8 Optional:完整参考
- Java 谓词示例 – 谓词过滤器
- Java 8 – 日期和时间示例
- Java 8 列出目录中的所有文件 – 六个示例
- Java 8 – 逐行读取文件
- Java 8 写入文件示例
- Java WatchService API 教程
- Java 8 解析字符串为日期
- Java 8 – 连接字符串数组 – 将数组转换为字符串
- Java Base64 编码和解码示例
- Math 类中的 Java 精确算术运算支持
- Java 8 带有 lambda 的Comparator示例
- 使用Pattern.compile()方法将 Java 正则表达式作为谓词
- Java 字符串连接(CSV)示例
- Java 8 两个日期之间的差异
- Java – 内部与外部迭代
- Java 中的安全随机数生成
- Java 7 教程
- Java 7 的更改,特性和增强
- Java 菱形运算符 – Java 中的<>运算符
- 带字符串的 Java switch case
- Java 7 中的try-with-resources
- Java 7 中数字字面值的下划线
- Java 抑制异常示例
- Java 7 – 异常处理增强
- Fork/Join 框架教程:ForkJoinPool示例
- 自动重新加载属性的 Java WatchService示例
- 面向对象原则
- Java OOP 概念 – 面向对象的原则
- Java 访问修饰符
- Java 构造器
- Java 实例初始化器块
- Java 中的抽象示例
- Java 封装与抽象
- Java 继承
- Java 多态示例
- Java 方法重载与方法重载
- 接口与 Java 中的抽象类
- Java extends与implements关键字
- Java instanceof运算符
- Java 中的多重继承
- 关联,聚合和组合
- Java 并发指南
- Java 并发教程
- Java 多线程的发展和主题
- Java 并发性 – 线程安全性?
- 并发与并行
- Java 比较和交换示例 – CAS 算法
- Java synchronized关键字
- Java 中的对象级别锁与类级别锁
- Java 中Runnable与Thread之间的区别
- 如何在 Java 中使用wait(),notify()和notifyAll()?
- Java 并发性 – yield()和join()之间的区别
- Java 中 sleep()和wait()之间的区别
- 锁和监视器之间的区别 – Java 并发
- Java Callable Future示例
- 如何使用UncaughtExceptionHandler重新启动线程
- 使用ThreadPoolExecutor和Semaphore限制任务提交率
- Java 执行器框架教程和最佳实践
- Java 线程间通信 – PipedReader和PipedWriter
- Java 死锁示例和解决方案
- Java 集合
- Java 中的集合
- Java 中的数组
- Java ArrayList指南
- Java LinkedList类
- Java HashMap指南
- Java Hashtable类
- Java LinkedHashMap类
- Java TreeMap类
- Java HashSet类
- Java LinkedHashSet类
- Java TreeSet类
- Java Comparable接口示例
- Java Comparator接口示例
- Java Iterator接口示例
- Java ListIterator接口
- Java Spliterator接口
- Java PriorityQueue类
- Java PriorityBlockingQueue类
- Java ArrayBlockingQueue类
- Java TransferQueue – Java LinkedTransferQueue类
- Java CopyOnWriteArrayList类
- Java CopyOnWriteArraySet类
- 如何在 Java 中对数组,列表,映射和集合进行排序
- Java 面试的 40 个热门问答集
- Java IO 教程
- Java IO 教程和示例
- Java I/O 如何在较低级别上内部工作?
- Java 标准 IO 与 Java NIO
- 如何在 Java 中复制目录
- 用 Java 递归删除目录
- Java – 创建新文件
- Java – 写入文件
- Java – 附加到文件
- Java 创建只读文件示例
- Java 将文件读取为字符串(已针对 Java 8 更新)
- Java 将文件读取到byte[]数组
- Java – 逐行读取文件 – LineNumberReader
- Java BufferedReader示例
- Java – BufferedWriter
- Java 读写属性文件示例
- 从资源文件夹读取文件 – Spring 示例
- Java – 读写 UTF-8 编码数据
- Java 中如何检查文件是否存在
- Java 文件复制 – 用 Java 复制文件的 4 种方法
- Java FilenameFilter示例 – 查找/删除某些扩展名的文件
- Java FileFilter示例
- Java – 创建临时文件
- Java – 写入临时文件
- Java – 删除临时文件
- Java – 读取控制台输入
- Java – 使用Scanner类读取类型安全输入
- 在 Java 中将字符串转换为InputStream
- 在 Java 中将InputStream转换为字符串
- Java – 创建受密码保护的 Zip 文件
- Java – 解压缩带有子目录的文件
- 使用 Java 在 Linux 中管理不超过 N GB 的系统日志文件
- 在 Java 中生成 SHA 或 MD5 文件校验和哈希
- Java 日期时间教程
- Java – 日期和时间 API
- Java – 日期验证
- Java – 日期格式
- Java LocalDate类
- Java LocalTime类
- Java LocalDateTime类
- Java ZonedDateTime类
- Java 8 – Period
- Java 8 DateTimeFormatter
- Java 8 – TemporalAdjusters
- Java 8 – TemporalQuery
- Java 8 – DayOfWeek
- Java 日期 – 解析,格式和转换
- Java 语言环境 – 创建和设置默认语言环境
- Java 枚举教程
- Java 枚举
- 带有字符串值的 Java 枚举
- 枚举真的是最好的单例吗?
- 枚举器和迭代器之间的区别?
- Java 异常
- Java try-finally块
- Java throw关键字
- Java 受检与非受检的异常
- Java 同步和异步异常
- Java NullPointerException - 如何在 Java 中有效处理空指针
- Java 自定义异常 – 最佳实践
- 构造器可以声明初始化器块中引发的受检异常
- Java 泛型教程
- 完整的 Java 泛型教程
- Java 泛型 PECS - 生产者extends消费者super
- Java 垃圾回收
- Java 垃圾收集算法(直到 Java 9)
- JVM 内存模型/结构和组件
- Java 内存管理 – 垃圾回收算法
- Java 序列化教程
- Java 序列化 – 执行正确的序列化
- Java serialVersionUID – 如何生成serialVersionUID
- Java 外部化示例 – 更有效的序列化
- Java 中Externalizable与Serializable之间的区别
- 将 Java 对象序列化为 XML – XMLEncoder和XMLDecoder示例
- Java 中反序列化过程如何发生?
- 使用readObject和writeObject的 Java 自定义序列化
- 使用内存序列化的 Java 深层复制
- 字符串方法
- Java String.concat()方法示例
- Java String.hashCode()方法示例
- Java String.contains()方法示例
- Java String.compareTo()方法示例
- Java String.compareToIgnoreCase()方法示例
- Java String.equals()方法 – 字符串比较
- Java String.equalsIgnoreCase()方法 – 不区分大小写的比较
- Java String.charAt()方法示例
- Java String.indexOf()方法示例
- Java String.lastIndexOf()方法示例
- Java String.intern()方法示例
- Java String.split()方法示例
- Java String.replace()方法示例
- Java String.replaceFirst()方法示例
- Java String.replaceAll()方法示例
- Java String.substring()方法示例
- Java String.startsWith()示例
- Java String.endsWith()方法示例
- Java String.toUpperCase()方法示例
- Java String.toLowerCase()方法示例
- Java 正则表达式教程
- Java 正则表达式教程
- Java 仅允许字母数字字符的正则表达式
- Java 正则表达式 – 信用卡号验证
- Java 正则表达式 – 加拿大邮政编码验证
- 货币符号的 Java 正则表达式
- 使用 Java 正则表达式进行日期验证
- 使用 Java 正则表达式进行电子邮件验证
- Java 正则表达式密码验证示例
- 适用于希腊语扩展或希腊语脚本的 Java 正则表达式
- 验证 ISBN(国际标准书号)的 Java 正则表达式
- 检查输入文本的最小/最大长度的 Java 正则表达式
- 限制文本中的行数的 Java 正则表达式
- 限制输入中的单词数的 Java 正则表达式
- 验证 SSN(社会安全号码)的 Java 正则表达式
- Java 正则表达式 – 英国邮政编码验证
- Java 正则表达式 – 美国邮政编码验证
- 验证商标符号的 Java 正则表达式
- 验证国际电话号码的 Java 正则表达式
- 北美电话号码的 Java 正则表达式
- Java NIO 教程
- NIO 教程
- 如何创建路径 – Java NIO
- 使用缓冲区 – Java NIO 2.0
- Java 通道教程 – NIO 2.0
- 3 种读取文件的方法 – Java NIO
- Java 8 – 逐行读取文件
- Java 内存映射文件 – Java MappedByteBuffer
- Java NIO – 分散/聚集或向量 IO
- 通道之间的数据传输 – Java NIO
- HowToDoInJava 其它教程
- Maven 教程
- 如何在 Windows 上安装 Maven
- Maven – 设置文件
- Maven – 依赖管理
- Maven 依赖范围
- Maven - POM 文件
- Maven – 父子 POM 示例
- Maven – 本地,远程和中央仓库
- Maven 本地仓库位置以及如何更改?
- M2_REPO – 在 Eclipse 中更改 Maven 仓库的位置
- Maven 代理设置 – Eclipse,命令行和全局设置
- Maven 强制最低 Java 版本
- Maven 创建 Java 项目 – 交互式与非交互式模式
- 在 Eclipse 中逐步创建 Maven Web 项目
- 多模块 Maven 项目 – 控制台
- Eclipse 中的 Maven 多模块项目
- Maven – 创建 Java 源文件夹
- Maven BOM – 物料清单依赖项
- 在 Eclipse 中导入 Maven 远程原型目录
- Eclipse 项目中的 Maven 自定义原型
- 已解决:Java 编译器级别与已安装的 Java 项目方面的版本不匹配
- Maven ant 插件 – 从pom.xml生成build.xml
- Maven IntelliJ IDEA 项目
- Spring MVC JSTL 配置示例
- Tomcat Maven 插件示例
- Maven – Spring Boot 胖/Uber Jar
- Maven Shade 插件 – UberJar/胖 Jar 示例
- Maven – 删除所有损坏的 jar/依赖项
- Gradle 教程 – 安装和 HelloWorld 示例
- Log4j2 教程
- Log4j2 JSON 配置示例
- Log4j2 属性文件示例
- Log4j2 xml 配置示例
- Log4j2 RollingFileAppender示例
- Log4j2 多个附加器示例
- Log4j2 LevelRangeFilter示例
- Log4j2 HTMLLayout配置示例
- Log4j2 ThreadContext – 相同事务的鱼标日志
- Log4j2 – 有用的转换模式示例
- 为 JUnit 测试用例配置 Log4j2
- Log4j 教程
- log4j.properties示例 – Log4j 属性文件示例
- log4j.xml示例 – Log4j xml 配置示例
- Log4j Maven 配置示例
- Log4j 日志级别 – Log4j2 日志级别示例
- Log4j ConsoleAppender配置示例
- Log4jRollingFileAppender配置示例
- Log4j SocketAppender和套接字服务器示例
- Log4j JDBCAppender – 在数据库中创建日志
- Log4j XMLLayout – 以 XML 格式创建日志
- Log4j HTMLLayout – 以 HTML 格式创建日志
- Log4j – 在运行时重新加载日志记录级别
- SLF4j 与 Log4j – 哪个更好?
- RESTEasy + Tomcat 7 + Log4j 日志记录示例
- Dropwizard 教程
- Dropwizard 教程
- Dropwizard 教程 – HelloWorld 示例
- Dropwizard – BasicAuth 安全示例
- Dropwizard 运行状况检查配置示例
- Dropwizard 客户端 – Jersey/HTTP 配置和示例
- [已解决] Dropwizard – 无法解析配置(无法将类型 ID “http”解析为子类型)
- RESTEasy 教程
- JAX-RS 2.0 教程
- RESTEasy + JBOSS 7 HelloWorld 应用
- 面向初学者的 RESTEasy 示例教程
- JAX-RS @Path URI 匹配 – 静态和正则 URI
- Java REST HATEOAS 示例
- RESTEasy + Tomcat 7 + SLF4J 日志示例
- RESTEasy + Tomcat 7 + Log4j 记录示例
- RESTEasy - 文件下载示例
- RESTEasy 文件上传 - HTML 表单示例
- RESTEasy 文件上传 - HttpClient示例
- 使用 Ajax 的 JAX-RS 自定义验证示例
- 使用 Hibernate 验证器供应器进行 RESTEasy Bean 验证
- RESTEasy ContainerRequestFilter - RESTEasy 安全过滤器示例
- RESTEasy 基本认证和授权教程
- RESTEasy JAXB XML 示例
- RESTEasy Jettison JSON 示例
- Jackson 的 RESTEasy JSON 示例
- RESTEasy ExceptionMapper – 异常处理示例
- RESTEasy 客户端 API
- 使用java.net包的 RESTful 客户端
- 使用 RESTful API 的 RESTEasy 客户端
- Apache HttpClient GET 和 POST 示例
- RESTEasy Javascript/Ajax 客户端演示
- JAX-RS 2.0 RESTEasy 3.0.2.Final 客户端 API 示例
- RESTEasy 最佳实践
- RESTEasy - 与ResteasyProviderFactory共享上下文数据
- RESTEasy ExceptionMapper – 异常处理示例
- 使用 ETag 的 RESTEasy 缓存控制示例
- RESTEasy – 启用 Gzip 压缩内容编码
- 比较 SOAP 与 RESTful Web 服务
- Jersey 教程
- Jersey HelloWorld 例子
- Jersey2 HelloWorld 示例 – Jersey2 教程
- jersey-quickstart-webapp HelloWorld 示例
- Jersey 使用过滤器记录请求和响应实体
- Jersey - 如何在 REST API 响应中设置 Cookie
- Jersey 文件下载示例 – StreamingOutput
- Jersey 文件上传示例 – Jersey2 MultiPartFeature
- Jersey - Ajax 多文件上传示例
- Jersey 异常处理 – Jersey ExceptionMapper示例
- Jersey + MOXy JSON 示例
- Jersey + JSONP 示例
- Jersey + Google Gson 示例
- Jersey REST API 安全示例
- Jersey 客户端
- Jersey 客户端示例 – Jersey2 客户端 API
- Jersey REST 客户端认证示例
- Jersey 客户端 - 设置 Cookie 示例
- JDBC 教程
- Java JDBC 教程
- Java – JDBC 连接示例(MySQL)
- Java – JDBC 驱动类型
- JDBC SELECT查询示例
- JDBC SQL INSERT查询示例
- JDBC SQL DELETE查询示例
- Java JDBC PreparedStatement示例
- JDBC 性能优化技巧
- Hiberate 教程
- Hiberate 教程
- Hibernate 示例 – HelloWorld 示例逐步简介
- Hibernate 获取实体示例 – get与load方法
- Hibernate 插入查询教程
- Hiberate 合并和刷新实体
- Hibernate 4 – 获取延迟加载的实体引用
- 从数据库中插入/选择 Blob 的 Hiberate 示例
- Hiberate save()和saveOrUpdate()方法
- Hiberate 实体/持久化生命周期状态
- Hibernate 4:如何构建SessionFactory
- Hiberate 实体等价和等同
- Hibernate JPA 级联类型
- Hibernate 延迟加载教程
- Hiberate 条件查询示例
- Hibernate HQL(Hiberate 查询语言)示例
- Hibernate @NamedQuery教程
- Hibernate – 如何定义实体之间的关联映射
- 通过示例了解 Hibernate 一级缓存
- Hiberate 二级缓存如何工作?
- Hibernate EhCache 配置教程
- Hibernate OSCache 配置示例教程
- Hibernate C3P0 连接池配置教程
- Hiberate 内存数据库
- Hibernate 验证器 – Java Bean 验证示例
- Hibernate 验证器 CDI – @HibernateValidator示例
- [已解决] UnexpectedTypeException - 找不到约束验证器
- Hiberate 注解
- Hibernate / JPA2 持久化注解教程
- Hiberate 注解与映射 – 优缺点
- @Immutable和@NaturalId – 特定于 Hiberate 的注解
- Hibernate @NaturalId示例教程
- Hiberate 一对多映射注解示例
- Hiberate 多对多映射注解示例
- Hiberate 一对一映射注解示例
- JUnit5 教程
- JUnit5 教程
- JUnit5 测试生命周期
- JUnit5 @BeforeAll注解示例
- JUnit5 @BeforeEach注解示例
- JUnit5 @AfterEach注解示例
- JUnit5 @AfterAll注解示例
- JUnit5 @RepeatedTest注解示例
- JUnit5 @Disabled测试示例
- JUnit5 @Tag注解示例
- JUnit5 预期的异常 – assertThrows()示例
- JUnit5 断言示例
- JUnit5 假设示例
- JUnit5 测试套件示例
- JUnit5 和 Gradle
- JUnit5 Maven 依赖项
- JUnit5 – 在 Eclipse 中执行测试
- Eclipse 的 JUnit5 测试模板
- JUnit5 与 JUnit4
- JUnit4 教程
- JUnit 教程
- JUnit 测试套件示例
- JUnit JUnitCore示例
- 使用 Maven 执行 JUnit 测试用例
- JUnit4 – 基于假设的测试用例
- Junit 预期异常测试用例示例
- JUnit 测试监听器– JUnit RunListener示例
- JUnit 测试超时 – JUnit5 超时示例
- JUnit 有序测试执行示例
- JUnit 参数化测试示例
- Junit 参数化测试 – @Theory和@DataPoints
- JUnit – 使用TemporaryFolder和@Rule创建临时文件/文件夹
- TestNG 教程
- TestNG 教程
- TestNG 教程(使用 Eclipse)
- 如何从 Maven 运行testng.xml
- TestNG 注解教程
- TestNG – 预期异常和预期消息教程
- TestNG – 如何禁用/忽略测试方法
- TestNG 并行执行测试,类和套件
- TestNG – 依赖测试示例
- TestNG – 超时测试教程
- TestNG @Parameters – 测试参数示例
- TestNG @DataProvider – 测试参数示例
- TestNG @Factory注解教程
- TestNG – @Factory和@DataProvider之间的区别
- TestNG 的前后注解
- TestNG – 测试组,元组,默认组示例
- Mockito 教程
- Mockito2 教程 – JUnit Mockito 示例
- Mockito 注解– @Mock,@Spy,@Captor,@InjectMock
- Mockito – @Mock和@InjectMock注解之间的区别
- Mockito – 验证具有不同参数的多个方法调用
- Spring Boot,Mockito 和 Junit – 单元测试服务层
- [已解决] IllegalStateException:无法初始化插件MockMaker
- 使用 PowerMock 进行模拟测试(带有 JUnit 和 Mockito)
- TypeScript 教程
- TypeScript 教程
- TypeScript 类型
- TypeScript 联合类型
- 字符串字面值类型
- TypeScript 变量 – var,let和const
- TypeScript 模板字符串
- TypeScript 算术运算符
- TypeScript 逻辑运算符
- TypeScript 比较运算符
- TypeScript for…of循环
- TypeScript 中的展开运算符
- TypeScript 中的数组
- TypeScript 中的枚举
- TypeScript 映射
- TypeScript 集合
- TypeScript 函数 – 剩余,可选和默认参数
- TypeScript 函数或方法重载
- 转译器(Transpiler)与编译器
- JavaScript 中的真值和假值
- 相等运算符(==)与严格相等运算符(===)
- JavaScript 中的undefined vs null
- JavaScript 变量提升
- tsconfig.json – TypeScript 编译器配置
- Angular(2.x)教程
- Angular 开发工作区设置
- [已解决] Npm 安装挂起或时间过长
- 模拟 REST 服务器来伪造在线 API
- Angular 插值
- Angular 组件
- Angular 模板和视图
- Angular 服务示例
- 带有 RxJS Observable的 Angular HttpClient示例
- AngularJS(1.x)教程
- AngularJS 教程 – HelloWorld 示例
- AngularJS – jQueryLite(jqLite)教程
- AngularJS 服务(内置和自定义)
- AngularJS Spring MVC Rest 示例
- JavaScript / jQuery 教程
- Ajax 教程 – 面向初学者的 Ajax 指南
- 完整的 jQuery Ajax($.ajax)教程
- jQuery 深度克隆示例
- jQuery 选择器 – 完整列表
- jQuery – 所有选择器(“*”) – 通用选择器
- jQuery – 检测剪切,复制或粘贴事件
- jQuery 检测ENTER键按下事件
- jQuery – Keypress和Keydown事件之间的区别
- 关于 StackOverflow 的最佳 jQuery 讨论
- JavaScript – 相等(==)与身份(===)运算符
- 您必须知道的 JavaScript 变量范围规则
- JavaScript:定义全局变量的正确方法
- 在 JavaScript 中实现 MVC 和 PubSub
- JavaScript DOM 对象与 jQuery 对象
- Jasmine 单元测试教程及示例
- JavaScript 日志 – 在 JSON 中屏蔽敏感信息
- Android 教程
- Android 教程:关键概念
- Android 教程:在 Windows 上安装 Android
- Android 教程:如何创建 Android 应用/项目
- Android 教程:Android 项目结构,文件和资源
- Android 清单:指定 Android 应用和 SDK 版本
- 如何加快缓慢的 Android AVD / 模拟器
- Hadoop 教程
- Hadoop – 大数据教程
- Hadoop MapReduce 初学者教程
- HDFS – Hadoop 分布式文件系统架构教程
- Brewer 的 CAP 定理简述
- Java 云开发简介和工具
- MongoDB 教程
- MongoDB 简介:为什么选择 MongoDB?
- 如何在 Windows 上安装 MongoDB
- Java MongoDB:使用 GridFS API 获取/保存图像
- Java MongoDB:在集合中插入文档的示例
- MongoDB 查找文档示例
- 微服务 – 定义,原理和好处
- Apache Kafka 教程
- Apache Kafka – 简介
- Apache Kafka – Windows 10 入门
- Kafka 的 Spring Boot – HelloWorld 示例
- Spring Boot Kafka JsonSerializer示例
- JMS 教程
- JMS 教程 – Java 消息服务教程
- JMS 点对点消息示例
- JMS 发布/订阅消息示例
- HornetQ 教程
- HornetQ 单体 – 基本的 JMS 消息传递示例
- 使用 Maven 的 HornetQ 独立服务器示例
- Spring3 Hornetq 独立集成示例
- Gson 教程
- Gson 教程
- Gson 安装
- GSON – 序列化和反序列化 JSON
- Gson – JSON 输出的精美打印
- GSON – 将 JSON 数组解析为 Java 数组或列表
- GSON – 序列化和反序列化 JSON 为集
- Gson – 序列化和反序列化包含自定义对象的HashMap
- Gson – GsonBuilder配置示例
- Gson - 序列化NULL值
- Gson @Since – 版本支持
- Gson @SerializedName
- Gson – 排除或忽略字段
- Gson - JsonReader
- Gson - JsonParser
- Gson – 自定义序列化和反序列化
- Gson – 快速指南
- JAXB 教程
- JAXB 注解
- JAXB @XmlRootElement注解示例
- JAXB @XmlElementWrapper注解示例
- JAXB Marshaller(编组器)示例
- JAXB Unmarshaller(解组器)示例
- JAXB 读取 XML 到 Java 对象的示例
- 使用 Moxy 和 Jaxb 将 JSON 转换为 Java 对象的示例
- JAXB 将 Java 对象写入 XML 的示例
- JAXB 将对象转换为 JSON 的示例
- JAXB – 在 Java 中编组和解组HashMap
- JAXB – 编组和解组对象列表或集合
- 使用 Eclipse 从 JAXB Java 类生成 XSD
- JAXB 模式验证
- [已解决]:javax.xml.bind.JAXBException:java.util.ArrayList或其任何超类不是此上下文的已知类
- [已解决]:线程“main”com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException中的异常:3 个IllegalAnnotationExceptions计数
- 没有@XmlRootElement的 JAXB 编组 – 缺少@XmlRootElement错误
- 不带 jaxb 注解的解组
- Jackson 教程
- Jackson2 – 将 Java 对象转换为 JSON,并将 JSON 字符串转换为对象
- Jackson 将对象转换为 json 并将 json 转换为对象
- Jackson – 将 JSON 转换为Map并将Map转换为 JSON
- Java XML 教程
- Java 读取 XML – Java DOM 解析器示例
- Java SAX 解析器 – XML 读取示例
- Java JDOM2 – XML 读取示例
- 使用 Java StAX 解析器读取 XML – 游标和迭代器 API
- DOM 与 Java 中的 SAX 解析器
- Java 将 XML 转换为属性 – 从 XML 文件读取属性
- Java 将属性文件转换为 XML 文件
- Java 字符串到 XML – 将字符串解析为 XML DOM 的示例
- Java XML 转换为字符串 – 将 XML 对象写入文件的示例
- Java XPath 示例 – XPath 教程
- Java xpath 示例 – 在 xml 文件上求值 xpath
- Java8 xpath 示例 – 在字符串上求值 xpath
- Java XPath 表达式示例
- Java XPath NamespaceContext – 命名空间解析示例
- Java XPath 从 XML 获取属性值
- 在 Java 中使用 xpath 查找具有属性值的 xml 元素
- Java XPath – 检查节点或属性是否存在?
- Eclipse 教程
- 在 Eclipse 中导入 Maven 远程原型目录
- 使用 Eclipse 快速搜索插件进行更快的文本搜索
- 如何在 Eclipse 中显示非英文 unicode(例如中文)字符
- 如何在 Eclipse 中增加控制台输出限制
- 创建 Eclipse 模板以加快 Java 编程
- 在 5 分钟内使 Eclipse 更快
- 如何在印地语中编译和运行 Java 程序
- Java 覆盖最终静态方法 – 方法是覆盖还是隐藏?
- [已解决] 在 Eclipse 的 Java 构建路径中找不到超类“javax.servlet.http.HttpServlet”
- 版本控制系统教程
- 分布式版本控制系统如何工作?
- 版本控制系统(VCS)如何工作?
- 如何从 Google Code 项目中签出源代码
- Tomcat 教程
- Tomcat – 架构和server.xml配置
- 如何在默认的 HTTP 端口 80 中运行 tomcat
- Tomcat – 启用/禁用目录列表
- Tomcat SSL 或 HTTPS 配置示例
- 通过单个服务器安装运行 Tomcat 的多个实例
- Tomcat Maven 插件示例
- Spring,Tomcat – 获取负载均衡器后面的真实 IP
- Web 服务器如何工作?
- Linux 教程
- JStack 线程转储分析器
- 使用 Java 在 Linux 中管理系统日志文件不超过 N GB
- Swagger – Spring REST 示例
- GoF 设计模式
- 设计模式
- 创建型设计模式
- Java 单例模式介绍
- Java 中的构建器设计模式
- Java 工厂模式说明
- 抽象工厂模式解释
- Java 中的原型设计模式
- 行为型设计模式
- 责任链设计模式
- 命令设计模式
- 迭代器设计模式
- 中介者设计模式
- 备忘录设计模式
- 观察者设计模式
- 状态设计模式
- 策略设计模式
- 模板方法设计模式
- 访问者设计模式示例
- 结构型设计模式
- Java 中的适配器设计模式
- 桥接设计模式
- 组合设计模式
- Java 中的装饰器设计模式
- 外观设计模式
- 享元设计模式
- 代理设计模式
- 设计原则
- Java 中的 SOLID 原则(含示例)
- 开闭原则
- 单一责任原则
- Java 最佳实践
- Java 最佳实践指南
- 编写好的单元测试的 FIRST 原则
- 您应该如何对 DAO 层进行单元测试
- JUnit 最佳实践指南
- 不良单元测试用例的 8 个迹象
- 20 个 Java 异常处理最佳实践
- 13 个编写 Spring 配置文件的最佳实践
- Java Web 应用性能改进技巧
- Java 算法
- Java 算法和实现
- 冒泡排序 Java 示例
- 插入排序 Java 示例
- 归并排序 Java 示例
- 快速排序 Java 示例
- 选择排序 Java 示例
- Java AES 加密解密示例
- 使用 Soundex 算法实现语音搜索
- Java 比较和交换示例 – CAS 算法
- Python 教程
- Python 教程
- 如何在 Sublime 编辑器中安装 Python 包
- Python – 注释
- Python – 变量
- Python – 数据类型
- Python – 关键字
- Python – 字符串
- Python – 列表
- Python – 元组
- Python max()和min()– 在列表或数组中查找最大值和最小值
- Python 找到 N 个最大的或最小的项目
- Python 读写 CSV 文件
- Python httplib2 – HTTP GET 和 POST 示例
- Python 将元组解包为变量或参数
- Python 解包元组 – 太多值无法解包
- Python 多重字典示例 – 将单个键映射到字典中的多个值
- Python OrderedDict – 有序字典
- Python 字典交集 – 比较两个字典
- Python 优先级队列示例
- RxJava 教程
- 完整的 Java Servlet 教程
- vaadin 教程
- 使用 Maven 的 vaadin HelloWorld Web 应用
- Vaadin ComboBox示例
- vaadin 文本字段示例
- Vaadin Spring Security BasicAuth 示例
- SQL 教程
- SQL – 不使用临时表删除重复行
- 查找员工的第 N 高薪的 SQL 查询
- SQLException:用户root@localhost的访问被拒绝
- Struts2 教程
- Struts2 HelloWorld 示例
- Struts2 HelloWorld 注解示例
- 使用@InterceptorRef的 Struts2 自定义拦截器示例
- Struts2 – 如何正确设置结果路径
- Spring4 + Struts2 + Hibernate 集成教程
- [已解决] 无法找到ref-name引用的拦截器类
- [已解决]:找不到扩展名properties或xml的结果类型
- 数据结构教程
- 使用数组的 Java 栈实现
- Java 中的自定义列表实现示例
- HTML5 教程
- HTML5 – <section>标签示例
- HTML5 字符集 – 字符编码声明
- HTML5 DOCTYPE声明示例
- Java 题目
- Java 面试题目与答案
- Java 中的无效代码和无法访问的代码
- Java 字符串回文 – Java 数字回文示例
- 检测LinkedList中的无限循环的示例
- 复合赋值运算符i += j与 Java 中的i = i + j不同
- Java 中的 HiLo 猜谜游戏
- Java 题目 – 查找所有重复的元素
- Java 题目 – TreeMap的放置操作
- 题目 – 返回所有字符串中的第 N 长字符串
- Java 题目:好的字符串 – 坏的字符串
- 题目 – 检查字符串是否完整(包含所有字母)
- Java 中的反转字符串 - 单词反转字符串
- 用 Java 计算阶乘的 3 种方法
- Java 中的 FizzBuzz 解决方案
- 从 Java 中的序列/数组中查找缺失的数字
- Java – 不使用“new”关键字创建对象
- 面试问题
- Java 面试问题
- Java 字符串面试问题与答案
- Java 核心面试问题 – 第 1 部分
- Java 核心面试问题 – 第 2 部分
- Java 核心面试问题 – 第 3 部分
- Java 面试的 40 个热门问答集
- 中级开发人员的 Java 面试问题
- 针对 Oracle 企业管理器项目的实际 Java 面试问题
- HashMap和ConcurrentHashMap面试问题
- Java 版本和新特性