Hibernate 3.2 引入基於 Java 5 註解的映射機制,結合 EJB 3 / JPA 標準,徹底改變持久化層開發體驗:映射資訊與領域模型合一、IDE 智能提示、重構安全、零 XML 維護成本。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
// 原生 Hibernate
SessionFactory sf = new AnnotationConfiguration().buildSessionFactory();
// Spring 整合
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.example.domain.User</value>
<value>com.example.domain.Order</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
@Entity
@Table(name = "T_USER", uniqueConstraints = @UniqueConstraint(columnNames = "EMAIL"))
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "USER_ID")
private Long id;
@Column(name = "USER_NAME", nullable = false, length = 50)
private String name;
@Column(name = "EMAIL", nullable = false, length = 100)
private String email;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "CREATED_AT", updatable = false)
private Date createdAt = new Date();
@Transient // 不持久化
private String tempPassword;
// Getters/Setters...
}
| 關聯類型 | 註解組合 | 關鍵屬性 |
|---|---|---|
| 多對一 (N:1) | @ManyToOne + @JoinColumn | cascade、fetch、optional、targetEntity |
| 一對多 (1:N) | @OneToMany(mappedBy="...") | cascade、fetch、orphanRemoval、@OrderBy |
| 一對一 (1:1) | @OneToOne + @JoinColumn / @PrimaryKeyJoinColumn | mappedBy、optional、cascade |
| 多對多 (N:M) | @ManyToMany + @JoinTable | joinColumns、inverseJoinColumns、cascade |
// Department.java
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OrderBy("name ASC")
private Set<Employee> employees = new HashSet<>();
// Employee.java
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPT_ID", nullable = false)
private Department department;
// 維護雙向關聯輔助方法
public void addEmployee(Employee emp) {
employees.add(emp);
emp.setDepartment(this);
}
@NamedQueries({
@NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email"),
@NamedQuery(name = "User.findActive", query = "SELECT u FROM User u WHERE u.active = true ORDER BY u.createdAt DESC"),
@NamedQuery(name = "User.deleteInactive", query = "DELETE FROM User u WHERE u.lastLogin < :date")
})
@Entity
public class User { ... }
// 使用方式
List<User> users = session.getNamedQuery("User.findByEmail")
.setParameter("email", "test@example.com")
.list();
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE):二級快取@BatchSize(size = 20):集合批次抓取@Filter(name = "tenantFilter", condition = "tenant_id = :tid"):動態資料過濾@Where(clause = "deleted = 0"):軟刪除自動過濾@Formula("(SELECT COUNT(*) FROM ORDER o WHERE o.user_id = USER_ID)"):衍生屬性@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime"):自訂類型org.hibernate.annotationsSerializable、覆寫 equals()/hashCode() (基於業務鍵)@MappedSuperclass 抽取共通欄位 (id、版本、審計欄位)hibernate.use_sql_comments=true 便於 SQL 追蹤Hibernate Annotations 將映射元資料從 XML 釋放,回歸領域模型核心。配合 JPA 標準與 Hibernate 擴充,既享受型別安全、重構友善的開發體驗,又保有強大靈活的進階功能。這是現代 Java 持久化層開發的標準範式。