# 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 UserDetailsS??ervice示例
- 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(jqLit??e)教程
- 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 中的 FizzBu??zz 解決方案
- 從 Java 中的序列/數組中查找缺失的數字
- Java – 不使用“new”關鍵字創建對象
- 面試問題
- Java 面試問題
- Java 字符串面試問題與答案
- Java 核心面試問題 – 第 1 部分
- Java 核心面試問題 – 第 2 部分
- Java 核心面試問題 – 第 3 部分
- Java 面試的 40 個熱門問答集
- 中級開發人員的 Java 面試問題
- 針對 Oracle 企業管理器項目的實際 Java 面試問題
- HashMap和ConcurrentHashMap面試問題
- Java 版本和新特性